d_satProof->collectClausesUsed(used_inputs, used_lemmas);
IdToSatClause::const_iterator it;
+ std::set<Node> seen;
for (it = used_lemmas.begin(); it != used_lemmas.end(); ++it) {
std::set<Node> lemma = satClauseToNodeSet(it->second);
continue;
recipe = getCnfProof()->getProofRecipe(lemma);
- if (recipe.simpleLemma() && recipe.getTheory() == theory) {
+ if (recipe.simpleLemma() && recipe.getTheory() == theory && seen.find(recipe.getOriginalLemma()) == seen.end()) {
lemmas.push_back(recipe.getOriginalLemma());
+ seen.insert(recipe.getOriginalLemma());
}
}
}
// During CNF conversion, conjunctions will be broken down into
// multiple lemmas. In order for the recipes to match, we have to do
// the same here.
+
+ NodeManager* nm = NodeManager::currentNM();
+
if (lemma.getKind() == kind::AND) {
for (unsigned i = 0; i < lemma.getNumChildren(); ++i)
registerLemmaRecipe(lemma[i], originalLemma, theoryId);
+ } else if (lemma.getKind() == kind::IFF) {
+ registerLemmaRecipe(nm->mkNode(kind::OR, lemma[0], lemma[1].negate()), originalLemma, theoryId);
+ registerLemmaRecipe(nm->mkNode(kind::OR, lemma[0].negate(), lemma[1]), originalLemma, theoryId);
}
// Theory lemmas have one step that proves the empty clause