private int getMaxChocoCardinality(Group group) {
   int maxCardinality = group.getMaxCardinality();
   int cardinality = maxCardinality;
   if (maxCardinality == -1) {
     // cardinality = Choco.MAX_UPPER_BOUND;
     cardinality = group.getChildFeatures().size();
   }
   return cardinality;
 }
 private void transformGroup(Group group) {
   createGroupConstraint(group);
   EList<Feature> childFeatures = group.getChildFeatures();
   for (Feature feature : childFeatures) {
     transformFeature(feature);
   }
 }
  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);
    }
  }
  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 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 int getMinChocoCardinality(Group group) {
   return group.getMinCardinality();
 }