// combine two clauses Clause operator+(const Clause &cl1, const Clause &cl2) { Clause newcl(cl1); ClauseIterator cl2Iter(cl2); for ( ; !cl2Iter.done(); cl2Iter++) { Literal cl2lit(cl2Iter()); cl2lit.setIndex(::nextIndex()); MustBeTrue(newcl.insert(cl2lit) == OK); } ClauseAnswersIterator cl2ansIter(cl2); for ( ; !cl2ansIter.done(); cl2ansIter++) { Literal cl2anslit(cl2ansIter()); cl2anslit.setIndex(::nextIndex()); MustBeTrue(newcl.insertAnswer(cl2anslit) == OK); } if (cl1.getSOS() || cl2.getSOS()) newcl.setSOS(1); if (cl1.getConclusion() || cl2.getConclusion()) newcl.setConclusion(1); if (cl1.getQuery() || cl2.getQuery()) newcl.setQuery(1); newcl.updateType(); return(newcl); }
// 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); } }
// 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); } }