// resolve two clauses, if possible. int resolveClauses(Array<OrderedSet<Clause> > &clausesArray, Clause &cl1, Clause &cl2, int &clausesAdded, unsigned int currentDepth) { // clear this flag clausesAdded = 0; // check if any of the clauses are empty if (cl1.isEmpty() || cl2.isEmpty()) { return(VALID); } // check if clauses can be resolved if (!cl1.getSOS() && cl2.getSOS()) { // one clause must be in the set-of-support return(NOMATCH); } if ((cl1.getType() == Clause::Negative && cl2.getType() == Clause::Negative) || (cl1.getType() == Clause::Positive && cl2.getType() == Clause::Positive)) { // two positive clauses or two negative clauses // can not be resolved. return(NOMATCH); } // attempt to resolve two clauses. use A-ordering resolution, // try to resolve maximal literals. // Literal maxlit1; if (cl1.getMaximalLiteral(maxlit1) != OK) { return(NOTOK); } Literal maxlit2; if (cl2.getMaximalLiteral(maxlit2) != OK) { return(NOTOK); } if (maxlit1 != ~maxlit2) { return(NOMATCH); } // factor clauses if (factor(maxlit1, cl1) == NOTOK) { return(NOTOK); } if (factor(maxlit2, cl2) == NOTOK) { return(NOTOK); } // attempt to unify the clauses Substitutions subs; if (unify(maxlit1, ~maxlit2, subs) != OK) { return(NOMATCH); } // can resolve, remove literals from clauses Clause newcl1(cl1); if (newcl1.remove(maxlit1, 1) != OK) { return(NOTOK); } if (subs.applyTo(newcl1) != OK) { return(NOTOK); } Clause newcl2(cl2); if (newcl2.remove(maxlit2, 1) != OK) { return(NOTOK); } if (subs.applyTo(newcl2) != OK) { return(NOTOK); } // store new clause and update flag Clause newcl = newcl1+newcl2; if (newcl.renameVariables() != OK) { return(NOTOK); } newcl.setDepth(currentDepth+1); newcl.setNumber(nextClause++); if (clausesArray[currentDepth+1].insert(newcl) != OK) { return(NOTOK); } clausesAdded = 1; // indicate the clauses that were resolved dumpnewclause(cl1, cl2, newcl); // check if we found an empty clause if (newcl.isEmpty()) { return(VALID); } else { return(OK); } }
// rename variables in clause int Clause::renameVariables() { Clause newcl; Map<String, String> nvs; // rename variables in positive clause BinaryTree_AVL_Iterator_InOrder<Literal> pclIter(positiveClause); for ( ; !pclIter.done(); pclIter++) { Literal literal(pclIter()); if (literal.renameVariables(nvs) != OK) { ERROR("renameVariables failed.", errno); return(NOTOK); } if (newcl.insert(literal) != OK) { ERROR("insert failed.", errno); return(NOTOK); } } // rename variables in negative clause BinaryTree_AVL_Iterator_InOrder<Literal> nclIter(negativeClause); for ( ; !nclIter.done(); nclIter++) { Literal literal(nclIter()); if (literal.renameVariables(nvs) != OK) { ERROR("renameVariables failed.", errno); return(NOTOK); } if (newcl.insert(literal) != OK) { ERROR("insert failed.", errno); return(NOTOK); } } // rename variables in answers clause ListIterator<Literal> ansIter(answers); for ( ; !ansIter.done(); ansIter++) { Literal literal(ansIter()); if (literal.renameVariables(nvs) != OK) { ERROR("renameVariables failed.", errno); return(NOTOK); } if (newcl.insertAnswer(literal) != OK) { ERROR("insert failed.", errno); return(NOTOK); } } #if 0 // update table of renamed variables if (updateVariableNames(nvs) != OK) return(NOTOK); #endif // overwrite existing clauses newcl.setDepth(getDepth()); newcl.setNumber(getNumber()); newcl.setConclusion(getConclusion()); newcl.setQuery(getQuery()); newcl.setSOS(getSOS()); *this = newcl; // all done return(OK); }
// resolve two clauses, if possible. int resolveClauses(Array<BinaryTree_AVL<Clause> > &clausesArray, Clause &cl1, Clause &cl2, int &clausesAdded, unsigned int currentDepth) { // check if any of the clauses are empty statistics[ResolutionsAttempted] += 1; totalstatistics[TotalResolutionsAttempted] += 1; if (cl1.isEmpty() || cl2.isEmpty()) { return(VALID); } // check if clauses can be resolved if (!cl1.getSOS() && !cl2.getSOS()) { // one clause must be in the set-of-support return(NOMATCH); } if ((cl1.getType() == Clause::Negative && cl2.getType() == Clause::Negative) || (cl1.getType() == Clause::Positive && cl2.getType() == Clause::Positive)) { // two positive clauses or two negative clauses // can not be resolved. return(NOMATCH); } // attempt to resolve two clauses. use A-ordering resolution, // try to resolve maximal literals. // Literal maxlit1; if (cl1.getMaximalLiteral(maxlit1) != OK) { ERROR("getMaximalLiteral failed.", errno); return(NOTOK); } Literal maxlit2; if (cl2.getMaximalLiteral(maxlit2) != OK) { ERROR("getMaximalLiteral failed.", errno); return(NOTOK); } if ((cl1.getTotalMembers() > maxliterals) || (cl2.getTotalMembers() > maxliterals)) { statistics[MaximumLiteralsClausesRejected] += 1; totalstatistics[TotalMaximumLiteralsClausesRejected] += 1; return(NOMATCH); } if (maxlit1.unify_ne(~maxlit2)) { return(NOMATCH); } // factor clauses Substitutions subs; if (factor(maxlit1, cl1, subs) == NOTOK) { ERROR("factor failed.", errno); return(NOTOK); } if (factor(maxlit2, cl2, subs) == NOTOK) { ERROR("factor failed.", errno); return(NOTOK); } // attempt to unify the clauses subs.clear(); int status = unify(maxlit1, ~maxlit2, subs); switch (status) { case OK: if (verbose) { cout << endl; Literal ml1(maxlit1); cout << "max literal 1 (before subs): " << ml1 << endl; subs.applyTo(ml1); cout << "max literal 1 (after subs): " << ml1 << endl; Literal ml2(maxlit2); cout << "max literal 2 (before subs): " << ml2 << endl; subs.applyTo(ml2); cout << "max literal 2 (after subs): " << ml2 << endl; MustBeTrue(equal(ml1, ~ml2)); } break; case NOMATCH: return(NOMATCH); default: ERROR("unify failed.", errno); return(status); } // can resolve, remove literals from clauses Clause newcl1(cl1); if (newcl1.remove(maxlit1) != OK) { ERROR("remove failed.", errno); return(NOTOK); } if (subs.applyTo(newcl1) != OK) { ERROR("applyTo failed.", errno); return(NOTOK); } Clause newcl2(cl2); if (newcl2.remove(maxlit2) != OK) { ERROR("remove failed.", errno); return(NOTOK); } if (subs.applyTo(newcl2) != OK) { ERROR("applyTo failed.", errno); return(NOTOK); } // store new clause and update flag Clause newcl = newcl1+newcl2; if (newcl.renameVariables() != OK) { ERROR("renameVariables failed.", errno); return(NOTOK); } newcl.setDepth(currentDepth+1); newcl.setNumber(nextClause++); if (clausesArray[currentDepth+1].insert(newcl) != OK) { ERROR("insert failed.", errno); return(NOTOK); } clausesAdded = 1; // indicate the clauses that were resolved statistics[ClausesGenerated] += 1; totalstatistics[TotalClausesGenerated] += 1; dumpnewclause(cl1, cl2, newcl); // check if we found an empty clause if (newcl.isEmpty()) { return(VALID); } else { return(OK); } }