private Constraint getMemberConstraint(Attribute attribute) {
    Constraint memberConstraint = null;

    IntegerVariable attributeValueVariable = getOrCreateVariable(attribute);

    // if attribute value is set, then the according attribute value must be
    // set
    if (FeatureModelHelper.isAttributeValueSet(attribute)) {
      int value = FeatureModelHelper.getAttributeValue(attribute);
      memberConstraint = Choco.eq(value, attributeValueVariable);
    } else {
      // check domain values
      Domain domain = attribute.getDomain();

      if (domain instanceof NumericalDomain) {
        NumericalDomain numericalDomain = (NumericalDomain) domain;
        // value of attribute must be in one of the intervals.
        int[] values = getNumericalValues(numericalDomain, attribute);
        memberConstraint = Choco.member(attributeValueVariable, values);

      } else if (domain instanceof DiscreteDomain) {
        DiscreteDomain discreteDomain = (DiscreteDomain) domain;
        int[] domainValues = discreteDomainValues.get(discreteDomain.getId());
        memberConstraint = Choco.member(attributeValueVariable, domainValues);
      }
    }
    return memberConstraint;
  }
 private Constraint createRequiresConstraint(Feature lf, Feature rf) {
   IntegerVariable leftFeature = getOrCreateVariable(lf);
   IntegerVariable rightFeature = getOrCreateVariable(rf);
   Constraint leftConstraint = Choco.gt(leftFeature, 0);
   Constraint rightConstraint = Choco.gt(rightFeature, 0);
   Constraint impliesConstraint = Choco.implies(leftConstraint, rightConstraint);
   return impliesConstraint;
 }
 protected void horizonConstraints(
     final IntegerVariable[] starts, final IntegerVariable[] durations) {
   if (horizon > 0) {
     for (int i = 0; i < starts.length; i++) {
       model.addConstraint(Choco.geq(horizon, Choco.plus(starts[i], durations[i])));
     }
   }
 }
  private Constraint getFeatureAttributeValueConstraint(
      IntegerVariable featureVariable, Constraint valueConstraint) {
    Constraint result = null;
    Constraint featureSelected = Choco.eq(featureVariable, 1);
    Constraint implies = Choco.implies(featureSelected, valueConstraint);
    result = Choco.implies(featureSelected, implies);

    return result;
  }
  private Constraint createAttributeConstraint(AttributeConstraint attributeConstraint) {
    Constraint result = null;

    Constraint constraint = null;
    AttributeOperand leftOperand = attributeConstraint.getLeftOperand();
    IntegerVariable leftOperandVariable = getVariableForAttributeOperand(leftOperand);

    AttributeOperand rightOperand = attributeConstraint.getRightOperand();
    IntegerVariable rightOperandVariable = getVariableForAttributeOperand(rightOperand);

    Relop operator = attributeConstraint.getOperator();
    switch (operator) {
      case EQUAL:
        constraint = Choco.eq(leftOperandVariable, rightOperandVariable);
        break;
      case GREATER_THAN:
        constraint = Choco.gt(leftOperandVariable, rightOperandVariable);
        break;
      case GREATER_THAN_OR_EQUAL:
        constraint = Choco.geq(leftOperandVariable, rightOperandVariable);
        break;
      case LESS_THAN:
        constraint = Choco.lt(leftOperandVariable, rightOperandVariable);
        break;
      case LESS_THAN_OR_EQUAL:
        constraint = Choco.leq(leftOperandVariable, rightOperandVariable);
        break;
      case UNEQUAL:
        constraint = Choco.neq(leftOperandVariable, rightOperandVariable);
        break;
      default:
        break;
    }

    IntegerVariable leftFeatureVariable = getFeatureVariableForOperand(leftOperand);
    IntegerVariable rightFeatureVariable = getFeatureVariableForOperand(rightOperand);
    // if both are features and both are selected, then the attribute constraint must be evaluated
    if (leftFeatureVariable != null && rightFeatureVariable != null) {
      Constraint leftFeatureSelected = Choco.eq(leftFeatureVariable, 1);
      Constraint rightFeatureSelected = Choco.eq(rightFeatureVariable, 1);
      Constraint and = Choco.and(leftFeatureSelected, rightFeatureSelected);
      result = Choco.implies(and, constraint);
    } else {
      // if one of the two operand is a constant,the constraint will be evaluated if the host
      // feature is selected
      if (leftFeatureVariable != null) {
        result = getFeatureAttributeValueConstraint(leftFeatureVariable, constraint);
      } else if (rightFeatureVariable != null) {
        result = getFeatureAttributeValueConstraint(rightFeatureVariable, constraint);
      }
    }

    return result;
  }
 public IntegerVariable[] generateRandomDurations(final int n) {
   final IntegerVariable[] durations = new IntegerVariable[n];
   final int gap = horizon / n;
   int max = gap + horizon % n;
   for (int i = 0; i < n - 1; i++) {
     final int v = RANDOM.nextInt(max) + 1;
     max += gap - v;
     durations[i] = Choco.constant(v);
   }
   durations[n - 1] = Choco.constant(max);
   return durations;
 }
 public void initializeTasks() {
   if (starts == null) {
     tasks = Choco.makeTaskVarArray("T", 0, horizon, durations);
   } else {
     tasks = new TaskVariable[durations.length];
     for (int i = 0; i < tasks.length; i++) {
       tasks[i] =
           Choco.makeTaskVar(
               String.format("T_%d", i),
               starts[i],
               Choco.makeIntVar(String.format("end-%d", i), 0, horizon, Options.V_BOUND),
               durations[i]);
     }
   }
 }
 private IntegerVariable getVariableForAttributeOperand(AttributeOperand operand) {
   IntegerVariable variable = null;
   if (operand instanceof AttributeReference) {
     AttributeReference attRef = (AttributeReference) operand;
     Attribute attribute = attRef.getAttribute();
     variable = getOrCreateVariable(attribute);
   } else if (operand instanceof AttributeValue) {
     AttributeValue value = (AttributeValue) operand;
     int valueInt = value.getInt();
     String valueName = value.getName();
     if (valueName != null && valueName.length() > 0) {
       AttributeOperand other = getOtherOperand(operand);
       if (other instanceof AttributeReference) {
         AttributeReference attRef = (AttributeReference) other;
         Domain domain = attRef.getAttribute().getDomain();
         if (domain instanceof DiscreteDomain) {
           DiscreteDomain discreteDomain = (DiscreteDomain) domain;
           EList<DomainValue> values = discreteDomain.getValues();
           for (DomainValue domainValue : values) {
             String name = domainValue.getName();
             if (valueName.equals(name)) {
               valueInt = domainValue.getInt();
               break;
             }
           }
         } else if (domain instanceof NumericalDomain) {
           valueInt = Integer.decode(valueName);
         }
       }
     }
     variable = Choco.constant(valueInt);
   }
   return variable;
 }
 /**
  * 此方法,将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));
         }
       }
     }
   }
 }
  private void transformAttribute(Attribute attribute) {
    // 0: attribute is disabled if feature is disabled
    // 1: attribute is enabled if feature is selected
    IntegerVariable featureVariable = getOrCreateVariable(attribute.getFeature());

    Constraint memberConstraint = getMemberConstraint(attribute);

    // if feature is enabled, then attribute value must be in bounds
    Constraint featureEnabled = Choco.eq(featureVariable, 1);
    Constraint checkAttribute = Choco.implies(featureEnabled, memberConstraint);
    getModel().addConstraint(checkAttribute);

    IntegerVariable attributeVariable = getOrCreateVariable(attribute);

    Constraint featureDisabled = Choco.eq(featureVariable, 0);
    Constraint attrDisabled = Choco.eq(attributeVariable, attributeDisabled);

    Constraint disabledAttr = Choco.ifOnlyIf(featureDisabled, attrDisabled);
    getModel().addConstraint(disabledAttr);
  }
  private IntegerVariable createAttributeValueVariable(Attribute attribute, String attributeId) {
    // String attrOptions = "cp:no_decision";
    String attrOptions = "";
    IntegerVariable attributeVariable = null;

    // (1) if attribute value is set, then attribute can either be this value or the disabled
    // attribute value
    if (FeatureModelHelper.isAttributeValueSet(attribute)) {
      int value = FeatureModelHelper.getAttributeValue(attribute);
      int[] attributeValues = new int[] {value, attributeDisabled};
      attributeVariable = Choco.makeIntVar(attributeId, attributeValues, attrOptions);
    } else {

      Domain attributeDomain = attribute.getDomain();

      // (2) if attribute domain is discrete
      if (attributeDomain instanceof DiscreteDomain) {
        DiscreteDomain discreteDomain = (DiscreteDomain) attributeDomain;
        int[] domainValues = getDomainValues(attribute, discreteDomain);
        attributeVariable = Choco.makeIntVar(attributeId, domainValues, attrOptions);

        // todo: check numerical domain and use intervals instead
        // (3) if attribute domain is integer
      } else if (attributeDomain instanceof NumericalDomain) {
        NumericalDomain numericalDomain = (NumericalDomain) attributeDomain;
        int lowestBoundofNumericalDomain = getLowestBoundofNumericalDomain(numericalDomain);
        int highestBoundofNumericalDomain = getHighestBoundofNumericalDomain(numericalDomain);
        if (lowestBoundofNumericalDomain > attributeDisabled) {
          lowestBoundofNumericalDomain = attributeDisabled;
        }
        attributeVariable =
            Choco.makeIntVar(
                attributeId,
                lowestBoundofNumericalDomain,
                highestBoundofNumericalDomain,
                attrOptions);
      }
    }
    return attributeVariable;
  }
  private void createGroupConstraint(Group group) {
    // group with cardinality {n,m} represented as
    // ifThen(ParentFeature>0;sum(ChildFeature A, ChildFeature
    // B) in {n,m};)
    // if group cardinality is n=m, then
    // ifThen(ParentFeature>0;sum(ChildFeature A, ChildFeature B) = n)
    log.debug("Create constraint for group " + group);
    IntegerVariable parentFeatureVariable = getOrCreateVariable((Feature) group.eContainer());

    IntegerExpressionVariable childFeatureSum = createChildFeatureVariable(group);
    int minCardinality = getMinChocoCardinality(group);
    int maxCardinality = getMaxChocoCardinality(group);

    Constraint ifConstraint = Choco.gt(parentFeatureVariable, 0);

    Constraint greaterThan = Choco.geq(childFeatureSum, minCardinality);
    Constraint smallerThan = Choco.leq(childFeatureSum, maxCardinality);

    Constraint thenConstraint = Choco.and(greaterThan, smallerThan);

    Constraint groupCardinalityConstraint = Choco.implies(ifConstraint, thenConstraint);
    getModel().addConstraint(groupCardinalityConstraint);
  }
  private IntegerVariable createFeatureVariable(Feature feature) {
    String id = feature.getId();
    // an unbound feature has cardinality [0..1],
    // a selected feature has cardinality [1..1],
    // a deselected feature has cardinality [0..0]
    int minCardinality = (FeatureState.SELECTED.equals(feature.getConfigurationState())) ? 1 : 0;
    int maxCardinality = (FeatureState.DESELECTED.equals(feature.getConfigurationState())) ? 0 : 1;

    log.debug(
        "Create IntegerVariable for '" + id + "' [" + minCardinality + "," + maxCardinality + "].");
    IntegerVariable intNodeVariable = Choco.makeIntVar(id, minCardinality, maxCardinality);
    getModel().addVariable(intNodeVariable);
    nodeVariables.put(id, intNodeVariable);
    return intNodeVariable;
  }
  private IntegerExpressionVariable createChildFeatureVariable(Group group) {
    EList<Feature> childFeatures = group.getChildFeatures();
    List<IntegerVariable> childFeatureVariables =
        new ArrayList<IntegerVariable>(childFeatures.size());
    for (Feature feature : childFeatures) {
      IntegerVariable childFeatureVariable = getOrCreateVariable(feature);
      childFeatureVariables.add(childFeatureVariable);
    }
    IntegerVariable[] childFeatureVariablesArray =
        new IntegerVariable[childFeatureVariables.size()];
    childFeatureVariablesArray = childFeatureVariables.toArray(childFeatureVariablesArray);

    IntegerExpressionVariable childFeatureSum = Choco.sum(childFeatureVariablesArray);
    log.debug("Create IntegerExpressionVariable for child features of group " + group);
    return childFeatureSum;
  }
  private Constraint createExcludesConstraint(Feature lf, Feature rf) {
    IntegerVariable leftFeature = getOrCreateVariable(lf);
    IntegerVariable rightFeature = getOrCreateVariable(rf);

    Constraint leftSelected = Choco.gt(leftFeature, 0);
    Constraint rightNotSelected = Choco.eq(rightFeature, 0);
    Constraint leftRight = Choco.implies(leftSelected, rightNotSelected);

    Constraint rightSelected = Choco.gt(rightFeature, 0);
    Constraint leftNotSelected = Choco.eq(leftFeature, 0);
    Constraint rightLeft = Choco.implies(rightSelected, leftNotSelected);

    Constraint excludeConstraint = Choco.or(leftRight, rightLeft);
    return excludeConstraint;
  }
  private void createFeatureConstraint(Feature feature) {
    IntegerVariable childVariable = getOrCreateVariable(feature);

    int minCardinality = 0;
    int maxCardinality = 1;

    Constraint greaterThan = Choco.geq(childVariable, minCardinality);
    Constraint smallerThan = Choco.leq(childVariable, maxCardinality);
    Constraint thenConstraint = Choco.and(greaterThan, smallerThan);

    EObject featureContainer = feature.eContainer();
    if (featureContainer instanceof Group) {
      Group parentGroup = (Group) featureContainer;

      EObject groupContainer = parentGroup.eContainer();
      if (groupContainer instanceof Feature) {
        Feature parentFeature = (Feature) groupContainer;

        IntegerVariable parentVariable = getOrCreateVariable(parentFeature);

        // feature value must be in feature cardinality boundaries
        Constraint parentSelected = Choco.gt(parentVariable, 0);
        Constraint parentSelectedAndChildCardinality =
            Choco.implies(parentSelected, thenConstraint);
        getModel().addConstraint(parentSelectedAndChildCardinality);

        Constraint childSelected = Choco.gt(childVariable, 0);
        Constraint impliesConstraint = Choco.implies(childSelected, parentSelected);
        getModel().addConstraint(impliesConstraint);
      }

    } else {
      // handle rootgroup
      Constraint greater = Choco.gt(childVariable, minCardinality);
      getModel().addConstraint(greater);
    }
  }
  /**
   * Detect different equalities cliques.
   *
   * @param matrix matrix of equalities
   * @param nbIntVars nb of IntegerVariable within the model
   * @param color array of colir, ie nb different variable
   * @param domainByColor list of domain by color.
   * @return nb of different color found
   */
  private int detect(
      final ISparseMatrix matrix,
      final int nbIntVars,
      final int[] color,
      final TIntObjectHashMap<IntegerVariableMerger> domainByColor) {
    int nb = -1;
    IntegerVariableMerger dtmp = new IntegerVariableMerger();
    final Iterator<Long> it = matrix.iterator();
    while (it.hasNext()) {
      final long v = it.next();
      final int i = (int) (v / nbIntVars);
      final int j = (int) (v % nbIntVars);

      if (color[i] == -1) {
        nb++;
        color[i] = nb;
        domainByColor.put(nb, new IntegerVariableMerger(model.getIntVar(i)));
      }
      final IntegerVariableMerger d = domainByColor.get(color[i]);
      // backup
      dtmp.copy(d);
      if (d.intersection(model.getIntVar(j))) {
        color[j] = color[i];
        domainByColor.put(color[i], d);
      } else {
        add(Choco.eq(model.getIntVar(i), model.getIntVar(j)));
        // rollback
        d.copy(dtmp);
        if (color[j] == -1) {
          nb++;
          color[j] = nb;
          domainByColor.put(nb, new IntegerVariableMerger(model.getIntVar(j)));
        }
      }
    }
    return nb;
  }
Beispiel #18
0
 public Object minus(Object exp, int value) {
   return Choco.minus((IntegerExpressionVariable) exp, value);
 }
Beispiel #19
0
 public Object mult(Object exp1, Object exp2) {
   return Choco.mult((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2);
 }
  public Constraint generateConstraint(
      ExpressionNode leftNode, ExpressionNode rightNode, InfixExpression.Operator operator) {
    IntegerExpressionVariable leftVariable = null, rightVariable = null;
    if (leftNode.getType() != ExpressionType.single_int) {
      leftVariable = constraintVariableModeling(leftNode);
    }
    if (rightNode.getType() != ExpressionType.single_int) {
      rightVariable = constraintVariableModeling(rightNode);
    }
    Constraint constraint = null;
    if (leftVariable != null && rightVariable != null) {
      if (operator.equals(InfixExpression.Operator.LESS)) {
        constraint = Choco.lt(leftVariable, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.LESS_EQUALS)) {
        constraint = Choco.leq(leftVariable, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.GREATER)) {
        constraint = Choco.gt(leftVariable, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.GREATER_EQUALS)) {
        constraint = Choco.geq(leftVariable, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.EQUALS)) {
        constraint = Choco.eq(leftVariable, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.NOT_EQUALS)) {
        constraint = Choco.neq(leftVariable, rightVariable);
      } else {
        System.out.println("Constraint solver can't do with the operator: " + operator);
      }
    } else if (leftVariable != null && rightVariable == null) {
      int rightValue = Integer.parseInt(rightNode.getValue());
      if (operator.equals(InfixExpression.Operator.LESS)) {
        constraint = Choco.lt(leftVariable, rightValue);
      } else if (operator.equals(InfixExpression.Operator.LESS_EQUALS)) {
        constraint = Choco.leq(leftVariable, rightValue);
      } else if (operator.equals(InfixExpression.Operator.GREATER)) {
        constraint = Choco.gt(leftVariable, rightValue);
      } else if (operator.equals(InfixExpression.Operator.GREATER_EQUALS)) {
        constraint = Choco.geq(leftVariable, rightValue);
      } else if (operator.equals(InfixExpression.Operator.EQUALS)) {
        constraint = Choco.eq(leftVariable, rightValue);
      } else if (operator.equals(InfixExpression.Operator.NOT_EQUALS)) {
        constraint = Choco.neq(leftVariable, rightValue);
      } else {
        System.out.println("Constraint solver can't do with the operator: " + operator);
      }
    } else if (leftVariable == null && rightVariable != null) {
      int leftValue = Integer.parseInt(leftNode.getValue());
      if (operator.equals(InfixExpression.Operator.LESS)) {
        constraint = Choco.lt(leftValue, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.LESS_EQUALS)) {
        constraint = Choco.leq(leftValue, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.GREATER)) {
        constraint = Choco.gt(leftValue, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.GREATER_EQUALS)) {
        constraint = Choco.geq(leftValue, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.EQUALS)) {
        constraint = Choco.eq(leftValue, rightVariable);
      } else if (operator.equals(InfixExpression.Operator.NOT_EQUALS)) {
        constraint = Choco.neq(leftValue, rightVariable);
      } else {
        System.out.println("Constraint solver can't do with the operator: " + operator);
      }
    } else if (leftVariable == null && rightVariable == null) {
      int leftValue = Integer.parseInt(leftNode.getValue()),
          rightValue = Integer.parseInt(rightNode.getValue());
      boolean logicResult;
      Constraint
          falseConstraint =
              Choco.lt(Choco.makeIntVar("bigger", 5, 6), Choco.makeIntVar("smaller", 1, 2)),
          trueConstraint =
              Choco.gt(Choco.makeIntVar("bigger", 5, 6), Choco.makeIntVar("smaller", 1, 2));

      if (operator.equals(InfixExpression.Operator.LESS)) {
        if (leftValue < rightValue) {
          constraint = trueConstraint;
        } else {
          constraint = falseConstraint;
        }
      } else if (operator.equals(InfixExpression.Operator.LESS_EQUALS)) {
        if (leftValue <= rightValue) {
          constraint = trueConstraint;
        } else {
          constraint = falseConstraint;
        }
      } else if (operator.equals(InfixExpression.Operator.GREATER)) {
        if (leftValue > rightValue) {
          constraint = trueConstraint;
        } else {
          constraint = falseConstraint;
        }
      } else if (operator.equals(InfixExpression.Operator.GREATER_EQUALS)) {
        if (leftValue >= rightValue) {
          constraint = trueConstraint;
        } else {
          constraint = falseConstraint;
        }
      } else if (operator.equals(InfixExpression.Operator.EQUALS)) {
        if (leftValue == rightValue) {
          constraint = trueConstraint;
        } else {
          constraint = falseConstraint;
        }
      } else if (operator.equals(InfixExpression.Operator.NOT_EQUALS)) {
        if (leftValue != rightValue) {
          constraint = trueConstraint;
        } else {
          constraint = falseConstraint;
        }
      } else {
        System.out.println("Constraint solver can't do with the operator: " + operator);
      }
    }
    if (constraint == null) {
      System.out.println("can't solve this kind of constraint");
    }
    return constraint;
  }
Beispiel #21
0
 public Object div(Object exp1, Object exp2) {
   return Choco.div((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2);
 }
Beispiel #22
0
 public Object geq(int value, Object exp) {
   return Choco.geq(value, (IntegerExpressionVariable) exp);
 }
Beispiel #23
0
 public Object geq(Object exp, int value) {
   return Choco.geq((IntegerExpressionVariable) exp, value);
 }
Beispiel #24
0
 public Object makeIntVar(String name, int min, int max) {
   return Choco.makeIntVar(name, min, max);
 }
Beispiel #25
0
 public Object geq(Object exp1, Object exp2) {
   return Choco.geq((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp1);
 }
Beispiel #26
0
 public Object minus(int value, Object exp) {
   return Choco.minus(value, (IntegerExpressionVariable) exp);
 }
Beispiel #27
0
 public Object plus(Object exp1, Object exp2) {
   return Choco.plus((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2);
 }
  /**
   * 对一个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;
  }