public static Expr toExpr(List<List<Expr>> ors) {
    List<Expr> tmpOrs = new ArrayList<Expr>();
    for (List<Expr> ands : ors) {
      Expr and = ExprUtils.andifyBalanced(ands);

      tmpOrs.add(and);
    }

    if (ors.size() == 0) {
      return NodeValue.FALSE;
    }

    Expr result = ExprUtils.orifyBalanced(tmpOrs);

    return result;
  }
  // FIXME This method removes redundant TRUEs from clauses
  public static Expr dnfToExpr(Set<Set<Expr>> dnf, boolean skipUnsatisfiable) {
    Set<Expr> exprs = new HashSet<Expr>();

    for (Set<Expr> clause : dnf) {

      if (clause.size() > 1 && clause.contains(NodeValue.TRUE)) {
        clause.remove(NodeValue.TRUE);
      }

      if (skipUnsatisfiable) {
        if (!ClauseUtils.isSatisfiable(clause)) {
          continue;
        }
      }

      exprs.add(ExprUtils.andifyBalanced(clause));
    }

    Expr result = ExprUtils.orifyBalanced(exprs);
    return result != null ? result : NodeValue.FALSE;
  }
  /**
   * For each clause determine the constant constraints, and return those, that are common to all
   * clauses.
   *
   * @param dnf
   */
  public static Map<Var, NodeValue> extractConstantConstraints(Set<Set<Expr>> dnf) {
    Map<Var, NodeValue> result = new HashMap<Var, NodeValue>();

    Iterator<Set<Expr>> clauseIt = dnf.iterator();
    if (!clauseIt.hasNext()) {
      return result;
    }

    Set<Expr> firstClause = clauseIt.next();
    for (Expr expr : firstClause) {
      Pair<Var, NodeValue> constraint = ExprUtils.extractConstantConstraint(expr);

      addConstantConstraint(result, constraint);
    }

    Set<Var> seenVars = new HashSet<Var>();
    while (clauseIt.hasNext()) {

      if (result.isEmpty()) {
        return result;
      }

      Set<Expr> clause = clauseIt.next();
      for (Expr expr : clause) {
        Pair<Var, NodeValue> constraint = ExprUtils.extractConstantConstraint(expr);
        if (constraint == null || !result.containsKey(constraint.getKey())) {
          continue;
        }

        addConstantConstraint(result, constraint);
        seenVars.add(constraint.getKey());
      }

      result.keySet().retainAll(seenVars);
      seenVars.clear();
    }

    return result;
  }
 public SortCondition(Node var, int dir) {
   this(ExprUtils.nodeToExpr(var), dir);
 }
 public static List<ExprList> toClauses(ExprList exprs) {
   Expr evaluated = eval(ExprUtils.andifyBalanced(exprs));
   return evaluated == null ? null : dnfToClauses(Collections.singleton(evaluated));
 }