@Override
  public void getConstraintCost(int owner, Assignment k, ConstraintCheckResult result) {

    KAryConstraint constraint = roots[owner].getConstraint(k);
    if (constraint == null) {
      result.set(0, 0);
    } else {
      constraint.getCost(k, result);
    }
  }
  /**
   * calculate the cost for the given assignment
   *
   * @param owner
   * @param a
   * @param result
   */
  @Override
  public void calculateCost(int owner, Assignment a, ConstraintCheckResult result) {
    List<KAryConstraint> constraintsToConsider = roots[owner].collectAllSubConstraints(a);

    int cost = 0;
    int cc = 0;
    if (constraintsToConsider != null) {
      for (KAryConstraint constraint : constraintsToConsider) {
        constraint.getCost(a, result);
        cost = Agt0DSL.boundedSum(cost, result.getCost());
        cc += result.getCheckCost();
      }
    }

    result.set(cost, cc);
  }
  private void insertKAryConstraint(int owner, KAryConstraint constraint, boolean replace) {
    roots[owner].add(constraint, replace);

    // update neighbores
    for (int p : constraint.getParicipients()) {
      if (owner != p) {
        addNeighbor(owner, p);
      }
    }
  }
 public void add(KAryConstraint constraint, boolean replace) {
   int[] participients = constraint.getParicipients();
   Arrays.sort(participients);
   _add(constraint, participients, 0, replace);
 }