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; }
public int compare(Clause clause1, Clause clause2) { if (clause1.getNumOfLiterals() < clause2.getNumOfLiterals()) { return -1; } else { return 1; } }
public static void main(String args[]) throws IOException { // Main array where we will store our initial clauses. ArrayList<Clause> Clauses = new ArrayList<Clause>(); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); // Creating data structure. System.out.println("How many clauses does your formula in the Conjuctive Normal Form have?"); int nClauses = Integer.parseInt(in.readLine()); System.out.println("Please introduce your clauses."); System.out.println("(Input description in the readme file."); for (int i = 0; i < nClauses; i++) { String literalsList = in.readLine(); String[] literals = literalsList.split(" "); Clause clause = new Clause(); for (int i1 = 0; i1 < literals.length; i1++) { clause.addLiteral(literals[i1]); } Clauses.add(clause); } // End of data structure if (DLL(Clauses)) { System.out.println("Result: The formula is satisfactable."); } else { System.out.println("Result: The formula is not satisfactable."); } }
/** * If the fomula contains a unit clause, return a list of unit clauses * * @return */ public ArrayList<Clause> getUnits() { ArrayList<Clause> retval = new ArrayList<Clause>(); for (Clause c : clauses) { if (c.isUnit()) retval.add(c); } return retval; }
/** * Remove clauses where variable v has value newValue. Also remove variables from clauses where it * has !newValue. */ public void reduce(int val, int newValue) { int newVariable = 0; int notVariable = 0; if (val < 0 && newValue == -1) { newVariable = val; } else if (val < 0 && newValue == 1) { newVariable = val * -1; } else { newVariable = val * newValue; } notVariable = -newVariable; Iterator<Clause> iter = clauses.iterator(); while (iter.hasNext()) { Clause c = iter.next(); for (int i = 0; i < c.getVariables().size(); i++) { int var = c.getVariables().get(i); if (var == newVariable) { /* remove this clause */ finalVars.add(newVariable); iter.remove(); break; } else if (var == notVariable) { c.getVariables().remove(i); i--; } } } }
/** * Gets the "flip value" of setting this var to newValue. If setting var to newValue resulted in * breaking two expressions and fixing one, the retval would be -1. * * @param val the variable to set * @param newValue the value of the variable (1 for true, -1 for false) */ public int getFlipValue(int val, int newValue) { int newVariable = 0; int notVariable = 0; int flipVal = 0; if (val < 0 && newValue == -1) { newVariable = val; } else if (val < 0 && newValue == 1) { newVariable = val * -1; } else { newVariable = val * newValue; } notVariable = -newVariable; for (Clause c : clauses) { int varSize = c.getVariables().size(); for (int i = 0; i < varSize; i++) { int var = c.getVariables().get(i); if (var == newVariable) { flipVal++; break; } else if (c.isSatisfied() && c.getSatisfiedVar() == notVariable) { flipVal--; } } } return flipVal; }
// ------------------------------------------------------------------------------- // 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)]; }
private Clause make(Literal... e) { Clause c = new Clause(); for (int i = 0; i < e.length; ++i) { c = c.add(e[i]); } return c; }
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; }
/** * Get all unsatisfied clauses * * @return */ public ArrayList<Clause> getUnsatisfied() { ArrayList<Clause> retval = new ArrayList<Clause>(); for (Clause c : clauses) { if (!c.isSatisfied()) { retval.add(c); } } return retval; }
@Test public void testChooseLiteral() { Clause c = cpqr; while (!(c.isEmpty())) { Literal l = c.chooseLiteral(); assertTrue(c.contains(l)); c = c.reduce(l.getNegation()); } }
/** * Goes through every variable in c, and if the flip value did not break anything, add it to * retval. * * @param val the variable to set * @param newValue the value of the variable (1 for true, -1 for false) */ public ArrayList<Integer> getPositiveFlips(Clause c) { ArrayList<Integer> retval = new ArrayList<Integer>(); int varSize = c.getVariables().size(); for (int i = 0; i < varSize; i++) { int var = c.getVariables().get(i); int newValue = (var < 0) ? -1 : 1; if (isPositiveFlip(var, newValue)) retval.add(var); } return retval; }
// 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; }
/** * Copy constructor * * @param f */ public Formula(Formula f) { this(); for (Clause c : f.getClauses()) { Clause temp = new Clause(); int varSize = c.getVariables().size(); for (int i = 0; i < varSize; i++) { Integer newVar = new Integer(c.getVariables().get(i)); temp.addVariable(newVar); } this.clauses.add(temp); } this.getFinalVars().addAll(f.getFinalVars()); }
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; }
public final Object nextElement() { final Clause dbCurrentClause = (Clause) m_selProgramEnum.nextElement(); // il riuso dello stesso oggetto Rule evita la creazione di nuovi // oggetti che pesano sul garbage collector m_rule.m_cons = (Clause) dbCurrentClause.copy(true); m_rule.m_dbCons = dbCurrentClause; // controlla se module_transaprent if (!m_bModuleTranparent) { m_rule.m_strModule = dbCurrentClause.getModuleName(); } return m_rule; }
// This is a simple function to print a formula in a readable fashion. static void printClauses(ArrayList<Clause> Clauses) { String formula = "{"; boolean first = true; if (Clauses.size() == 0) formula = "{EMPTY}"; else { for (Clause c : Clauses) { if (first) { formula += c.printClause(); first = false; } else formula += " && " + c.printClause(); } formula += "}"; } System.out.println(formula); }
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; }
/** * Returns true if flipping this variable breaks nothing, false otherwise * * @param val * @param newValue * @return */ public boolean isPositiveFlip(int val, int newValue) { int newVariable = 0; int notVariable = 0; if (val < 0 && newValue == -1) { newVariable = val; } else if (val < 0 && newValue == 1) { newVariable = val * -1; } else { newVariable = val * newValue; } notVariable = -newVariable; for (Clause c : clauses) { int varSize = c.getVariables().size(); for (int i = 0; i < varSize; i++) { if (c.isSatisfied() && c.getSatisfiedVar() == notVariable) { return false; } } } return true; }
/** * 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); }
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); }
@Override public Object getValueAt(int row, int col) { Clause tempClause = clauses.get(row); switch (col) { case TITLE_COL: return tempClause.gettitle(); case KEYWORD_COL: return tempClause.getkeyword(); case DESCRIPTION_COL: return tempClause.getdescription(); case TEXT_COL: return tempClause.gettext(); default: return tempClause.getkeyword(); } }
/** * Sets the variable in the formula * * @param val the variable to set * @param newValue the value of the variable (1 for true, -1 for false) */ public void setVariable(int val, int newValue) { int newVariable = 0; int notVariable = 0; if (val < 0 && newValue == -1) { newVariable = val; } else if (val < 0 && newValue == 1) { newVariable = val * -1; } else { newVariable = val * newValue; } notVariable = -newVariable; for (Clause c : clauses) { int varSize = c.getVariables().size(); for (int i = 0; i < varSize; i++) { int var = c.getVariables().get(i); if (var == newVariable) { c.setSatisfiedVar(var); break; } else if (c.isSatisfied() && c.getSatisfiedVar() == notVariable) { c.setSatisfiedVar(0); } } } }
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())); }
/** * Adds the provided clause to this WHERE clause. * * @param clause the clause to add. * @return this WHERE clause. */ public Where and(Clause clause) { clauses.add(clause); statement.maybeAddRoutingKey(clause.name(), clause.firstValue()); setDirty(); return this; }
/* This is the main algorithm. * It receives a formula and processes it until * it can return true or false. */ static boolean DLL(ArrayList<Clause> Clauses) { // Unitary Propagation while (true) { String literalToRemove = searchSingleLiteral(Clauses); if (!literalToRemove.equals("NotFoundYet")) { printClauses(Clauses); System.out.println("Performing unitary propagation with: " + literalToRemove); removeClauses(literalToRemove, Clauses); cutClauses(literalToRemove, Clauses); printClauses(Clauses); if (Clauses.size() == 0) { System.out.println("All clauses removed. Returning true."); return true; } if (hasFalsehood(Clauses)) { System.out.println("Falsehood detected. Returning false."); return false; } else if (hasEmptyClause(Clauses)) { System.out.println("Empty clause detected. Returning false."); return false; } } else { System.out.println("No single literals."); System.out.println("Cannot perform unitary propagation."); break; } } ArrayList<Clause> copy1 = new ArrayList<Clause>(); ArrayList<Clause> copy2 = new ArrayList<Clause>(); for (Clause c : Clauses) { Clause c2 = new Clause(); for (String s : c.literals) { c2.addLiteral(s); } copy1.add(c2); } for (Clause c : Clauses) { Clause c2 = new Clause(); for (String s : c.literals) { c2.addLiteral(s); } copy2.add(c2); } Clause clause1 = new Clause(); Clause clause2 = new Clause(); String l1 = pickLiteral(Clauses); String l2 = ""; if (l1.startsWith("-")) l2 = l1.substring(1); else l2 = "-" + l1; clause1.addLiteral(l1); clause2.addLiteral(l2); copy1.add(clause1); copy2.add(clause2); // Moment of the truth System.out.println("Adding clause: [" + l1 + "]"); if (DLL(copy1) == true) { return true; } else { System.out.println("Trying opposite clause: [" + l2 + "]"); return DLL(copy2); } }
private Clause resolve(Clause mainPremise, Clause sidePremise, int mainPremiseAtomIndex) { // Rename the variables of the side premise int numberOfVariablesMainPremise = mainPremise.getVariables().size(); Clause sidePremiseRenamed = sidePremise.renameVariables( this.m_saturator.getTermFactory(), numberOfVariablesMainPremise); Term mainAtom = mainPremise.getBody()[mainPremiseAtomIndex]; Term sideAtom = sidePremiseRenamed.getHead(); Substitution unifier = Substitution.mostGeneralUnifier(mainAtom, sideAtom, this.m_saturator.getTermFactory()); if (unifier == null) return null; Set<Term> newBody = new LinkedHashSet<Term>(); // Copy the atoms from the main premise for (int index = 0; index < mainPremise.getBody().length; index++) { if (index != mainPremiseAtomIndex) { Term newBodyAtom = mainPremise.getBody()[index].apply(unifier, this.m_saturator.getTermFactory()); ((FunctionalTerm) newBodyAtom).originIndex = ((FunctionalTerm) mainPremise.getBody()[index]).originIndex; newBody.add(newBodyAtom); } } // Copy the atoms from the side premise for (int index = 0; index < sidePremiseRenamed.getBody().length; index++) { Term newBodyAtom = sidePremiseRenamed.getBody()[index].apply(unifier, this.m_saturator.getTermFactory()); ((FunctionalTerm) newBodyAtom).originIndex = ((FunctionalTerm) mainAtom).originIndex; newBody.add(newBodyAtom); } // New body and head Term[] body = new Term[newBody.size()]; newBody.toArray(body); Term head = mainPremise.getHead().apply(unifier, this.m_saturator.getTermFactory()); Clause resolvent = new Clause(body, head); // Rename variables in resolvent ArrayList<Variable> variablesResolvent = resolvent.getVariables(); HashMap<Variable, Integer> variableMapping = new HashMap<Variable, Integer>(); for (int i = 0; i < variablesResolvent.size(); i++) { variableMapping.put(variablesResolvent.get(i), i); } Clause resolventRenamed = resolvent.renameVariables(this.m_saturator.getTermFactory(), variableMapping); return resolventRenamed; }
public ArrayList<Clause> generateResolvents( Clause givenClause, Collection<Clause> workedOffClauses) { ArrayList<Clause> result = new ArrayList<Clause>(); // If the head of givenClause is selected, then givenClause is the side premise if (givenClause.m_selectedHead) { for (Clause workedOffClause : workedOffClauses) { for (int mainPremiseIndex = 0; mainPremiseIndex < workedOffClause.getBody().length; mainPremiseIndex++) { // If the body atom B of workedOffClause is selected and B has the same arity/name as the // head atom of givenClause, then try to resolve // System.out.println("Given: " + givenClause.getHead().getName()); // System.out.println(workedOffClause.getBody()[mainPremiseIndex].getName()); if ((workedOffClause.m_selectedBody[mainPremiseIndex]) && (workedOffClause.getBody()[mainPremiseIndex].getArity() == givenClause.getHead().getArity()) && (workedOffClause .getBody()[mainPremiseIndex] .getName() .equals(givenClause.getHead().getName()))) { Clause resolvent = resolve(workedOffClause, givenClause, mainPremiseIndex); if (resolvent != null) { result.add(resolvent); } } } } } // If a body atom of givenClause is selected, then givenClause is the main premise for (int mainPremiseIndex = 0; mainPremiseIndex < givenClause.getBody().length; mainPremiseIndex++) { if (givenClause.m_selectedBody[mainPremiseIndex]) { for (Clause workedOffClause : workedOffClauses) { // If the head atom B of workedOffClause is selected and B has the same arity/name as the // body atom of givenClause, then try to resolve if (workedOffClause.m_selectedHead && workedOffClause.getHead().getArity() == givenClause.getBody()[mainPremiseIndex].getArity() && workedOffClause .getHead() .getName() .equals(givenClause.getBody()[mainPremiseIndex].getName())) { Clause resolvent = resolve(givenClause, workedOffClause, mainPremiseIndex); if (resolvent != null) { result.add(resolvent); } } } } } return result; }