public static Set<DefaultRule> selectNonisomorphicDefaultRules(
     Iterable<DefaultRule> defaultRules) {
   List<Clause> candidates = new ArrayList<Clause>();
   for (DefaultRule rule : defaultRules) {
     DefaultRule preprocessed = preprocess(rule);
     candidates.add(
         new Clause(
             Sugar.<Literal>iterable(
                 preprocessed.antecedent().literals(), preprocessed.consequent().literals())));
   }
   Matching m = new Matching();
   Set<DefaultRule> retVal = new HashSet<DefaultRule>();
   for (Clause c : m.nonisomorphic(candidates)) {
     List<Literal> head = new ArrayList<Literal>();
     List<Literal> body = new ArrayList<Literal>();
     for (Literal l : c.literals()) {
       Literal newLiteral =
           new Literal(
               l.predicate().substring(l.predicate().indexOf(":") + 1), l.isNegated(), l.arity());
       for (int i = 0; i < l.arity(); i++) {
         newLiteral.set(l.get(i), i);
       }
       if (l.predicate().startsWith("antecedent:")
           || l.predicate().startsWith(SymmetricPredicates.PREFIX + "antecedent:")) {
         body.add(newLiteral);
       } else {
         head.add(newLiteral);
       }
     }
     retVal.add(new DefaultRule(new Clause(body), new Clause(head)));
   }
   return retVal;
 }
Пример #2
0
 public int compare(Clause clause1, Clause clause2) {
   if (clause1.getNumOfLiterals() < clause2.getNumOfLiterals()) {
     return -1;
   } else {
     return 1;
   }
 }
  // -------------------------------------------------------------------------------
  // find the literal that minimizes the number of UNSAT clauses
  private int findLiteral(boolean[] minterm) {
    int num_lits = cnf.num_lits, best = -Integer.MAX_VALUE, tos = 0;

    for (int i = 0; i < cnf.curr; i++)
      cnf.clauses[i].flag = cnf.clauses[i].satisfies(minterm) ? 1 : 0;

    for (int i = 0; i < num_lits; i++) {
      int sat = 0;
      for (Enumeration e = cnf.vars[i].occurs.elements(); e.hasMoreElements(); ) {
        Clause c = (Clause) e.nextElement();
        boolean was_sat = (c.flag == 1);
        minterm[i] = !minterm[i];
        boolean new_sat = c.satisfies(minterm);
        minterm[i] = !minterm[i];
        if (was_sat && !new_sat) sat--;
        if (!was_sat && new_sat) sat++;
      }
      if (sat > best) {
        tos = 0;
        best = sat;
      }
      if (best == sat) stack[tos++] = i;
    }
    return (tos == 0) ? random(num_lits) : stack[random(tos)];
  }
 public static Literal allDiffLiteral(Clause c) {
   Literal l = new Literal(SpecialVarargPredicates.ALLDIFF, c.variables().size());
   int i = 0;
   for (Variable v : c.variables()) {
     l.set(v, i++);
   }
   return l;
 }
Пример #5
0
 // make private?
 public Clause maxClause() {
   Clause maxClause = null;
   for (Clause clause : clauses) {
     if (maxClause == null || clause.ordinal() > maxClause.ordinal()) {
       maxClause = clause;
     }
   }
   assert maxClause != null;
   return maxClause;
 }
 private static MultiMap<Variable, Variable> surelyDifferent(DefaultRule rule) {
   Clause body = rule.antecedent();
   Clause head = rule.consequent();
   final MultiMap<Variable, Variable> different = new MultiMap<Variable, Variable>();
   for (Literal literal :
       Sugar.union(
           body.getLiteralsByPredicate(SpecialBinaryPredicates.NEQ),
           body.getLiteralsByPredicate(SpecialBinaryPredicates.GT),
           body.getLiteralsByPredicate(SpecialBinaryPredicates.LT),
           body.getLiteralsByPredicate(SpecialVarargPredicates.ALLDIFF),
           head.getLiteralsByPredicate(SpecialBinaryPredicates.NEQ),
           head.getLiteralsByPredicate(SpecialBinaryPredicates.GT),
           head.getLiteralsByPredicate(SpecialBinaryPredicates.LT),
           head.getLiteralsByPredicate(SpecialVarargPredicates.ALLDIFF))) {
     for (Term a : literal.terms()) {
       if (a instanceof Variable) {
         Variable v1 = (Variable) a;
         for (Term b : literal.terms()) {
           if (b instanceof Variable) {
             Variable v2 = (Variable) b;
             if (v1 != v2) {
               different.put(v1, v2);
             }
           }
         }
       }
     }
   }
   return different;
 }
Пример #7
0
  public boolean resolve(LinkedList<Clause> clauses) {
    // Storing onto the stack to verify clauses in reverse order
    // LinkedList<Clause> expansionStack = new LinkedList<Clause>();
    PriorityQueue<Clause> expansionQueue =
        new PriorityQueue<Clause>(10000, new ClauseSizeComparator());

    for (int count = 0; count < clauses.size(); count++) {
      expansionQueue.add(clauses.get(count));
    }

    while (!expansionQueue.isEmpty()) // Until the stack is empty
    {

      Clause lastClause = expansionQueue.poll();

      for (int clauseCount = 0; clauseCount < lastClause.getClauseID() - 1; clauseCount++) {
        // If any new clauses are added since last execution
        // if(!clauses.getLast().equals(lastClause))
        {
          // break;
        }

        Clause tempClause = clauses.get(clauseCount);
        int numClausesBeforeExpansion = clauses.size();
        boolean result = lastClause.resolution(tempClause, clauses);

        if (!result) {
          return false;
        }

        int numClausesAfterExpansion = clauses.size();

        // System.out.println(numClausesAfterExpansion - numClausesBeforeExpansion); //Size does not
        // change

        // If new clauses are added, expand the newly added clause before expanding any other clause
        if (numClausesAfterExpansion - numClausesBeforeExpansion > 0) {
          expansionQueue.add(clauses.getLast());
        }
      }
    }

    return true;
  }
Пример #8
0
 /**
  * Once you have a Result of implementing a child relational expression, call this method to
  * create a Builder to implement the current relational expression by adding additional clauses
  * to the SQL query.
  *
  * <p>You need to declare which clauses you intend to add. If the clauses are "later", you can
  * add to the same query. For example, "GROUP BY" comes after "WHERE". But if they are the same
  * or earlier, this method will start a new SELECT that wraps the previous result.
  *
  * <p>When you have called {@link Builder#setSelect(org.eigenbase.sql.SqlNodeList)}, {@link
  * Builder#setWhere(org.eigenbase.sql.SqlNode)} etc. call {@link
  * Builder#result(org.eigenbase.sql.SqlNode, java.util.Collection, org.eigenbase.rel.RelNode)}
  * to fix the new query.
  *
  * @param rel Relational expression being implemented
  * @param clauses Clauses that will be generated to implement current relational expression
  * @return A builder
  */
 public Builder builder(JdbcRel rel, Clause... clauses) {
   final Clause maxClause = maxClause();
   boolean needNew = false;
   for (Clause clause : clauses) {
     if (maxClause.ordinal() >= clause.ordinal()) {
       needNew = true;
     }
   }
   SqlSelect select;
   Expressions.FluentList<Clause> clauseList = Expressions.list();
   if (needNew) {
     select = subSelect();
   } else {
     select = asSelect();
     clauseList.addAll(this.clauses);
   }
   clauseList.addAll(Arrays.asList(clauses));
   Context newContext;
   final SqlNodeList selectList = select.getSelectList();
   if (selectList != null) {
     newContext =
         new Context(selectList.size()) {
           @Override
           public SqlNode field(int ordinal) {
             final SqlNode selectItem = selectList.get(ordinal);
             switch (selectItem.getKind()) {
               case AS:
                 return ((SqlCall) selectItem).operand(0);
             }
             return selectItem;
           }
         };
   } else {
     newContext = new AliasContext(aliases, aliases.size() > 1);
   }
   return new Builder(rel, clauseList, select, newContext);
 }
Пример #9
0
  public void printProofTree(Clause finalClause, LinkedList<Clause> clauseList) {
    PriorityQueue<Integer> proofTree =
        new PriorityQueue<
            Integer>(); // Will be used to order the ancestors of the finalClause for output
    LinkedList<Clause> treeQueue =
        new LinkedList<
            Clause>(); // Will take in the ancestors of the finalClause. Dequeue each element, add
                       // it to the proofTree, then add the parents to the queue
    int[] parentIDs;

    treeQueue.add(finalClause);
    while (!treeQueue.isEmpty()) {
      Clause polledClause = treeQueue.poll();

      if (proofTree.contains(
          polledClause
              .getClauseID())) // Skip this iteration if the clause has already been added to the
                               // proofTree
      {
        continue;
      }
      proofTree.add(polledClause.getClauseID());
      parentIDs = polledClause.getParentIDs();
      if (parentIDs[0]
          != -1) // if one parent exists, the other must exist and we add the parents to the queue
      {
        treeQueue.add(clauseList.get(parentIDs[0] - 1)); // add the first parent to the queue
        treeQueue.add(clauseList.get(parentIDs[1] - 1)); // add the second parent to the queue
      }
    }

    // output all the clauses in the proof tree
    while (proofTree.peek() != null) {
      clauseList.get(proofTree.poll() - 1).outputClause();
    }
  }
 public static boolean isomorphic(DefaultRule a, DefaultRule b) {
   a = preprocess(a);
   b = preprocess(b);
   Matching m = new Matching();
   Clause ca = new Clause(Sugar.iterable(a.antecedent().literals(), a.consequent().literals()));
   Clause cb = new Clause(Sugar.iterable(b.antecedent().literals(), b.consequent().literals()));
   return ca.variables().size() == cb.variables().size()
       && ca.literals().size() == cb.literals().size()
       && m.isomorphism(ca, cb);
 }
 private static Clause preprocessClause(Clause c, String prefix) {
   List<Literal> newLiterals = new ArrayList<Literal>();
   int specialID = 0;
   for (Literal l : c.literals()) {
     String predicate = l.predicate();
     if (predicate.equals(SpecialBinaryPredicates.NEQ)
         || predicate.equals(SpecialBinaryPredicates.EQ)
         || predicate.equals(SpecialVarargPredicates.ALLDIFF)) {
       predicate = SymmetricPredicates.PREFIX + prefix + predicate;
     } else {
       predicate = prefix + predicate;
     }
     Literal newLit = new Literal(predicate, l.isNegated(), l.arity());
     for (int i = 0; i < l.arity(); i++) {
       newLit.set(l.get(i), i);
     }
     newLiterals.add(newLit);
   }
   return new Clause(newLiterals);
 }
 public static void main(String[] args) {
   DefaultRule a = new DefaultRule(Clause.parse("a(X)"), Clause.parse("a(Y)"));
   DefaultRule b = new DefaultRule(Clause.parse("a(A)"), Clause.parse("a(B)"));
   DefaultRule c = new DefaultRule(Clause.parse("a(A)"), Clause.parse("a(A)"));
   DefaultRule d = new DefaultRule(Clause.parse("a(A,a)"), Clause.parse("b(B,b)"));
   DefaultRule e = new DefaultRule(Clause.parse("a(A,b)"), Clause.parse("b(B,a)"));
   DefaultRule f = new DefaultRule(Clause.parse("a(A,c)"), Clause.parse("b(B,d)"));
   for (DefaultRule r : selectNonisomorphicDefaultRules(Sugar.list(a, b, c, d))) {
     System.out.println(r);
   }
   System.out.println(
       partitionInterchangeableConstants(Sugar.list(a, b, c, d, e, f), Sugar.<Clause>set()));
 }
  public static MultiMap<DefaultRule, DefaultRule> representativeBodySpecializations(
      DefaultRule rule, List<Set<Constant>> interchangeableConstants) {
    Clause body = rule.antecedent();
    Clause head = rule.consequent();
    final MultiMap<Variable, Variable> different = surelyDifferent(rule);

    final List<Variable> variables = Sugar.<Variable>listFromCollections(body.variables());
    List<Integer> indices = VectorUtils.toList(VectorUtils.sequence(0, variables.size() - 1));
    List<Tuple<Integer>> unifications =
        Combinatorics.<Integer>cartesianPower(
            indices,
            indices.size(),
            new Sugar.Fun<Tuple<Integer>, Boolean>() {
              @Override
              public Boolean apply(Tuple<Integer> integerTuple) {
                for (int i = 0; i < integerTuple.size(); i++) {
                  if (integerTuple.get(i) > i
                      || !integerTuple.get(i).equals(integerTuple.get(integerTuple.get(i)))
                      || different
                          .get(variables.get(integerTuple.get(i)))
                          .contains(variables.get(i))
                      || !sameType(variables.get(integerTuple.get(i)), variables.get(i))) {
                    return Boolean.FALSE;
                  }
                }
                return Boolean.TRUE;
              }
            });

    Set<DefaultRule> nonIsomorphicUnifications = new HashSet<DefaultRule>();
    for (Tuple<Integer> unification : unifications) {
      Map<Term, Term> substitution = new HashMap<Term, Term>();
      for (int i = 0; i < unification.size(); i++) {
        substitution.put(variables.get(i), variables.get(unification.get(i)));
      }
      Clause newBody = LogicUtils.substitute(rule.antecedent(), substitution);
      Clause newHead = LogicUtils.substitute(rule.consequent(), substitution);
      nonIsomorphicUnifications.add(
          new DefaultRule(
              newBody.variables().size() > 1
                  ? new Clause(Sugar.union(newBody.literals(), allDiffLiteral(newBody)))
                  : newBody,
              newHead));
    }

    nonIsomorphicUnifications =
        DefaultTransformationUtils.selectNonisomorphicDefaultRules(nonIsomorphicUnifications);

    MultiMap<DefaultRule, DefaultRule> retVal = new MultiMap<DefaultRule, DefaultRule>();

    // this needs to be improved... e.g. using typing information...
    MultiList<Integer, Constant> consts = new MultiList<Integer, Constant>();
    int index = 0;
    for (Set<Constant> interch : interchangeableConstants) {
      consts.putAll(index++, interch);
    }
    for (DefaultRule unifiedRule : nonIsomorphicUnifications) {
      List<Variable> unifsVariables = Sugar.listFromCollections(unifiedRule.variables());
      if (unifsVariables.isEmpty()) {
        retVal.put(unifiedRule, unifiedRule);
      } else {
        Set<DefaultRule> substituted = new HashSet<DefaultRule>();
        middleLoop:
        for (Tuple<Integer> tuple :
            Combinatorics.cartesianPower(
                new NaturalNumbersList(0, interchangeableConstants.size()),
                unifsVariables.size())) {
          Counters<Integer> used = new Counters<Integer>();
          Map<Term, Term> substitution = new HashMap<Term, Term>();
          for (int i = 0; i < unifsVariables.size(); i++) {
            int j = used.incrementPost(tuple.get(i));
            if (j >= consts.get(tuple.get(i)).size()) {
              continue middleLoop;
            } else {
              if (unifsVariables.get(i).type() == null) {
                substitution.put(
                    unifsVariables.get(i),
                    Variable.construct(
                        unifsVariables.get(i).name(), consts.get(tuple.get(i)).get(j).type()));
              } else {
                if (unifsVariables.get(i).type().equals(consts.get(tuple.get(i)).get(j).type())) {
                  substitution.put(
                      unifsVariables.get(i),
                      Variable.construct(
                          unifsVariables.get(i).name(), consts.get(tuple.get(i)).get(j).type()));
                } else {
                  continue middleLoop;
                }
              }
            }
          }
          substituted.add(DefaultTransformationUtils.substitute(unifiedRule, substitution));
        }
        retVal.putAll(
            unifiedRule, DefaultTransformationUtils.selectNonisomorphicDefaultRules(substituted));
      }
    }
    return retVal;
  }