summaryrefslogtreecommitdiff
path: root/src/proof/proof_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/proof/proof_manager.cpp')
-rw-r--r--src/proof/proof_manager.cpp1032
1 files changed, 21 insertions, 1011 deletions
diff --git a/src/proof/proof_manager.cpp b/src/proof/proof_manager.cpp
index 99e3010b4..3e6cc9c69 100644
--- a/src/proof/proof_manager.cpp
+++ b/src/proof/proof_manager.cpp
@@ -21,14 +21,10 @@
#include "context/context.h"
#include "expr/node_visitor.h"
#include "options/bv_options.h"
-#include "options/proof_options.h"
+#include "options/smt_options.h"
#include "proof/clause_id.h"
#include "proof/cnf_proof.h"
-#include "proof/lfsc_proof_printer.h"
-#include "proof/proof_utils.h"
-#include "proof/resolution_bitvector_proof.h"
#include "proof/sat_proof_implementation.h"
-#include "proof/theory_proof.h"
#include "smt/smt_engine.h"
#include "smt/smt_engine_scope.h"
#include "smt/smt_statistics_registry.h"
@@ -39,36 +35,16 @@
#include "theory/uf/theory_uf.h"
#include "theory/valuation.h"
#include "util/hash.h"
-#include "util/proof.h"
namespace CVC4 {
-std::string nodeSetToString(const std::set<Node>& nodes) {
- std::ostringstream os;
- std::set<Node>::const_iterator it;
- for (it = nodes.begin(); it != nodes.end(); ++it) {
- os << *it << " ";
- }
- return os.str();
-}
-
-std::string append(const std::string& str, uint64_t num) {
- std::ostringstream os;
- os << str << num;
- return os.str();
-}
-
-ProofManager::ProofManager(context::Context* context, ProofFormat format)
+ProofManager::ProofManager(context::Context* context)
: d_context(context),
d_satProof(nullptr),
d_cnfProof(nullptr),
- d_theoryProof(nullptr),
- d_inputFormulas(),
d_inputCoreFormulas(context),
d_outputCoreFormulas(context),
d_nextId(0),
- d_fullProof(),
- d_format(format),
d_deps(context)
{
}
@@ -78,19 +54,6 @@ ProofManager::~ProofManager() {}
ProofManager* ProofManager::currentPM() {
return smt::currentProofManager();
}
-const Proof& ProofManager::getProof(SmtEngine* smt)
-{
- if (!currentPM()->d_fullProof)
- {
- Assert(currentPM()->d_format == LFSC);
- currentPM()->d_fullProof.reset(new LFSCProof(
- smt,
- getSatProof(),
- static_cast<LFSCCnfProof*>(getCnfProof()),
- static_cast<LFSCTheoryProofEngine*>(getTheoryProofEngine())));
- }
- return *(currentPM()->d_fullProof);
-}
CoreSatProof* ProofManager::getSatProof()
{
@@ -104,45 +67,8 @@ CnfProof* ProofManager::getCnfProof()
return currentPM()->d_cnfProof.get();
}
-TheoryProofEngine* ProofManager::getTheoryProofEngine()
-{
- Assert(currentPM()->d_theoryProof != NULL);
- return currentPM()->d_theoryProof.get();
-}
-
-UFProof* ProofManager::getUfProof() {
- Assert(options::proof());
- TheoryProof* pf = getTheoryProofEngine()->getTheoryProof(theory::THEORY_UF);
- return (UFProof*)pf;
-}
-
-proof::ResolutionBitVectorProof* ProofManager::getBitVectorProof()
-{
- Assert(options::proof());
- TheoryProof* pf = getTheoryProofEngine()->getTheoryProof(theory::THEORY_BV);
- return static_cast<proof::ResolutionBitVectorProof*>(pf);
-}
-
-ArrayProof* ProofManager::getArrayProof() {
- Assert(options::proof());
- TheoryProof* pf = getTheoryProofEngine()->getTheoryProof(theory::THEORY_ARRAYS);
- return (ArrayProof*)pf;
-}
-
-ArithProof* ProofManager::getArithProof() {
- Assert(options::proof());
- TheoryProof* pf = getTheoryProofEngine()->getTheoryProof(theory::THEORY_ARITH);
- return (ArithProof*)pf;
-}
-
-SkolemizationManager* ProofManager::getSkolemizationManager() {
- Assert(options::proof() || options::unsatCores());
- return &(currentPM()->d_skolemizationManager);
-}
-
void ProofManager::initSatProof(Minisat::Solver* solver)
{
- Assert(d_format == LFSC);
// Destroy old instance before initializing new one to avoid issues with
// registering stats
d_satProof.reset();
@@ -153,150 +79,22 @@ void ProofManager::initCnfProof(prop::CnfStream* cnfStream,
context::Context* ctx)
{
Assert(d_satProof != nullptr);
- Assert(d_format == LFSC);
- d_cnfProof.reset(new LFSCCnfProof(cnfStream, ctx, ""));
+ d_cnfProof.reset(new CnfProof(cnfStream, ctx, ""));
// true and false have to be setup in a special way
Node true_node = NodeManager::currentNM()->mkConst<bool>(true);
Node false_node = NodeManager::currentNM()->mkConst<bool>(false).notNode();
d_cnfProof->pushCurrentAssertion(true_node);
- d_cnfProof->pushCurrentDefinition(true_node);
d_cnfProof->registerConvertedClause(d_satProof->getTrueUnit());
d_cnfProof->popCurrentAssertion();
- d_cnfProof->popCurrentDefinition();
d_cnfProof->pushCurrentAssertion(false_node);
- d_cnfProof->pushCurrentDefinition(false_node);
d_cnfProof->registerConvertedClause(d_satProof->getFalseUnit());
d_cnfProof->popCurrentAssertion();
- d_cnfProof->popCurrentDefinition();
-}
-
-void ProofManager::initTheoryProofEngine()
-{
- Assert(d_theoryProof == NULL);
- Assert(d_format == LFSC);
- d_theoryProof.reset(new LFSCTheoryProofEngine());
-}
-
-std::string ProofManager::getInputClauseName(ClauseId id,
- const std::string& prefix) {
- return append(prefix+".pb", id);
-}
-
-std::string ProofManager::getLemmaClauseName(ClauseId id,
- const std::string& prefix) {
- return append(prefix+".lemc", id);
}
-std::string ProofManager::getLemmaName(ClauseId id, const std::string& prefix) {
- return append(prefix+"lem", id);
-}
-
-std::string ProofManager::getLearntClauseName(ClauseId id,
- const std::string& prefix) {
- return append(prefix+".cl", id);
-}
-std::string ProofManager::getVarName(prop::SatVariable var,
- const std::string& prefix) {
- return append(prefix+".v", var);
-}
-std::string ProofManager::getAtomName(prop::SatVariable var,
- const std::string& prefix) {
- return append(prefix+".a", var);
-}
-std::string ProofManager::getLitName(prop::SatLiteral lit,
- const std::string& prefix) {
- return append(prefix+".l", lit.toInt());
-}
-
-std::string ProofManager::getPreprocessedAssertionName(Node node,
- const std::string& prefix) {
- if (currentPM()->d_assertionFilters.find(node) != currentPM()->d_assertionFilters.end()) {
- return currentPM()->d_assertionFilters[node];
- }
-
- node = node.getKind() == kind::BITVECTOR_EAGER_ATOM ? node[0] : node;
- return append(prefix+".PA", node.getId());
-}
-std::string ProofManager::getAssertionName(Node node,
- const std::string& prefix) {
- return append(prefix+".A", node.getId());
-}
-std::string ProofManager::getInputFormulaName(const Expr& expr) {
- return currentPM()->d_inputFormulaToName[expr];
-}
-
-std::string ProofManager::getAtomName(TNode atom,
- const std::string& prefix) {
- prop::SatLiteral lit = currentPM()->d_cnfProof->getLiteral(atom);
- Assert(!lit.isNegated());
- return getAtomName(lit.getSatVariable(), prefix);
-}
-
-std::string ProofManager::getLitName(TNode lit,
- const std::string& prefix) {
- std::string litName = getLitName(currentPM()->d_cnfProof->getLiteral(lit), prefix);
- if (currentPM()->d_rewriteFilters.find(litName) != currentPM()->d_rewriteFilters.end()) {
- return currentPM()->d_rewriteFilters[litName];
- }
-
- return litName;
-}
-
-bool ProofManager::hasLitName(TNode lit) {
- return currentPM()->d_cnfProof->hasLiteral(lit);
-}
-
-std::string ProofManager::sanitize(TNode node) {
- Assert(node.isVar() || node.isConst());
-
- std::string name = node.toString();
- if (node.isVar()) {
- std::replace(name.begin(), name.end(), ' ', '_');
- } else if (node.isConst()) {
- name.erase(std::remove(name.begin(), name.end(), '('), name.end());
- name.erase(std::remove(name.begin(), name.end(), ')'), name.end());
- name.erase(std::remove(name.begin(), name.end(), ' '), name.end());
- name = "const" + name;
- }
-
- return name;
-}
-
-void ProofManager::traceDeps(TNode n, ExprSet* coreAssertions) {
- Debug("cores") << "trace deps " << n << std::endl;
- if ((n.isConst() && n == NodeManager::currentNM()->mkConst<bool>(true)) ||
- (n.getKind() == kind::NOT && n[0] == NodeManager::currentNM()->mkConst<bool>(false))) {
- return;
- }
- if(d_inputCoreFormulas.find(n.toExpr()) != d_inputCoreFormulas.end()) {
- // originating formula was in core set
- Debug("cores") << " -- IN INPUT CORE LIST!" << std::endl;
- coreAssertions->insert(n.toExpr());
- } else {
- Debug("cores") << " -- NOT IN INPUT CORE LIST!" << std::endl;
- if(d_deps.find(n) == d_deps.end()) {
- if (options::allowEmptyDependencies()) {
- Debug("cores") << " -- Could not track cause assertion. Failing silently." << std::endl;
- return;
- }
- InternalError()
- << "Cannot trace dependence information back to input assertion:\n`"
- << n << "'";
- }
- Assert(d_deps.find(n) != d_deps.end());
- std::vector<Node> deps = (*d_deps.find(n)).second;
- for(std::vector<Node>::const_iterator i = deps.begin(); i != deps.end(); ++i) {
- Debug("cores") << " + tracing deps: " << n << " -deps-on- " << *i << std::endl;
- if( !(*i).isNull() ){
- traceDeps(*i, coreAssertions);
- }
- }
- }
-}
void ProofManager::traceDeps(TNode n, CDExprSet* coreAssertions) {
Debug("cores") << "trace deps " << n << std::endl;
@@ -311,10 +109,6 @@ void ProofManager::traceDeps(TNode n, CDExprSet* coreAssertions) {
} else {
Debug("cores") << " -- NOT IN INPUT CORE LIST!" << std::endl;
if(d_deps.find(n) == d_deps.end()) {
- if (options::allowEmptyDependencies()) {
- Debug("cores") << " -- Could not track cause assertion. Failing silently." << std::endl;
- return;
- }
InternalError()
<< "Cannot trace dependence information back to input assertion:\n`"
<< n << "'";
@@ -345,16 +139,11 @@ void ProofManager::traceUnsatCore() {
IdToSatClause::const_iterator it = used_inputs.begin();
for(; it != used_inputs.end(); ++it) {
Node node = d_cnfProof->getAssertionForClause(it->first);
- ProofRule rule = d_cnfProof->getProofRule(node);
- Debug("cores") << "core input assertion " << node << std::endl;
- Debug("cores") << "with proof rule " << rule << std::endl;
- if (rule == RULE_TSEITIN ||
- rule == RULE_GIVEN) {
- // trace dependences back to actual assertions
- // (this adds them to the unsat core)
- traceDeps(node, &d_outputCoreFormulas);
- }
+ Debug("cores") << "core input assertion " << node << "\n";
+ // trace dependences back to actual assertions
+ // (this adds them to the unsat core)
+ traceDeps(node, &d_outputCoreFormulas);
}
}
@@ -373,150 +162,32 @@ std::vector<Expr> ProofManager::extractUnsatCore() {
return result;
}
-void ProofManager::constructSatProof() {
- if (!d_satProof->proofConstructed()) {
+void ProofManager::constructSatProof()
+{
+ if (!d_satProof->proofConstructed())
+ {
d_satProof->constructProof();
}
}
-void ProofManager::getLemmasInUnsatCore(theory::TheoryId theory, std::vector<Node> &lemmas) {
- Assert(PROOF_ON()) << "Cannot compute unsat core when proofs are off";
- Assert(unsatCoreAvailable())
- << "Cannot get unsat core at this time. Mabye the input is SAT?";
-
- constructSatProof();
-
- IdToSatClause used_lemmas;
- IdToSatClause used_inputs;
- d_satProof->collectClausesUsed(used_inputs, used_lemmas);
-
- IdToSatClause::const_iterator it;
- std::set<Node> seen;
-
- Debug("pf::lemmasUnsatCore") << "Dumping all lemmas in unsat core" << std::endl;
- for (it = used_lemmas.begin(); it != used_lemmas.end(); ++it) {
- std::set<Node> lemma = satClauseToNodeSet(it->second);
- Debug("pf::lemmasUnsatCore") << nodeSetToString(lemma);
-
- // TODO: we should be able to drop the "haveProofRecipe" check.
- // however, there are some rewrite issues with the arith solver, resulting
- // in non-registered recipes. For now we assume no one is requesting arith lemmas.
- LemmaProofRecipe recipe;
- if (!getCnfProof()->haveProofRecipe(lemma)) {
- Debug("pf::lemmasUnsatCore") << "\t[no recipe]" << std::endl;
- continue;
- }
-
- recipe = getCnfProof()->getProofRecipe(lemma);
- Debug("pf::lemmasUnsatCore") << "\t[owner = " << recipe.getTheory()
- << ", original = " << recipe.getOriginalLemma() << "]" << std::endl;
- if (recipe.simpleLemma() && recipe.getTheory() == theory && seen.find(recipe.getOriginalLemma()) == seen.end()) {
- lemmas.push_back(recipe.getOriginalLemma());
- seen.insert(recipe.getOriginalLemma());
- }
- }
-}
-
-std::set<Node> ProofManager::satClauseToNodeSet(prop::SatClause* clause) {
- std::set<Node> result;
- for (unsigned i = 0; i < clause->size(); ++i) {
- prop::SatLiteral lit = (*clause)[i];
- Node node = getCnfProof()->getAtom(lit.getSatVariable());
- Expr atom = node.toExpr();
- if (atom != utils::mkTrue())
- result.insert(lit.isNegated() ? node.notNode() : node);
- }
-
- return result;
-}
-
-Node ProofManager::getWeakestImplicantInUnsatCore(Node lemma) {
- Assert(PROOF_ON()) << "Cannot compute unsat core when proofs are off";
+void ProofManager::getLemmasInUnsatCore(std::vector<Node>& lemmas)
+{
+ Assert(options::unsatCores())
+ << "Cannot compute unsat core when proofs are off";
Assert(unsatCoreAvailable())
<< "Cannot get unsat core at this time. Mabye the input is SAT?";
-
- // If we're doing aggressive minimization, work on all lemmas, not just conjunctions.
- if (!options::aggressiveCoreMin() && (lemma.getKind() != kind::AND))
- return lemma;
-
constructSatProof();
-
- NodeBuilder<> builder(kind::AND);
-
IdToSatClause used_lemmas;
IdToSatClause used_inputs;
d_satProof->collectClausesUsed(used_inputs, used_lemmas);
-
+ Debug("pf::lemmasUnsatCore") << "Retrieving all lemmas in unsat core\n";
IdToSatClause::const_iterator it;
- std::set<Node>::iterator lemmaIt;
-
- if (!options::aggressiveCoreMin()) {
- for (it = used_lemmas.begin(); it != used_lemmas.end(); ++it) {
- std::set<Node> currentLemma = satClauseToNodeSet(it->second);
-
- // TODO: we should be able to drop the "haveProofRecipe" check.
- // however, there are some rewrite issues with the arith solver, resulting
- // in non-registered recipes. For now we assume no one is requesting arith lemmas.
- LemmaProofRecipe recipe;
- if (!getCnfProof()->haveProofRecipe(currentLemma))
- continue;
-
- recipe = getCnfProof()->getProofRecipe(currentLemma);
- if (recipe.getOriginalLemma() == lemma) {
- for (lemmaIt = currentLemma.begin(); lemmaIt != currentLemma.end(); ++lemmaIt) {
- builder << *lemmaIt;
-
- // Check that each conjunct appears in the original lemma.
- bool found = false;
- for (unsigned i = 0; i < lemma.getNumChildren(); ++i) {
- if (lemma[i] == *lemmaIt)
- found = true;
- }
-
- if (!found)
- return lemma;
- }
- }
- }
- } else {
- // Aggressive mode
- for (it = used_lemmas.begin(); it != used_lemmas.end(); ++it) {
- std::set<Node> currentLemma = satClauseToNodeSet(it->second);
-
- // TODO: we should be able to drop the "haveProofRecipe" check.
- // however, there are some rewrite issues with the arith solver, resulting
- // in non-registered recipes. For now we assume no one is requesting arith lemmas.
- LemmaProofRecipe recipe;
- if (!getCnfProof()->haveProofRecipe(currentLemma))
- continue;
-
- recipe = getCnfProof()->getProofRecipe(currentLemma);
- if (recipe.getOriginalLemma() == lemma) {
- NodeBuilder<> disjunction(kind::OR);
- for (lemmaIt = currentLemma.begin(); lemmaIt != currentLemma.end(); ++lemmaIt) {
- disjunction << *lemmaIt;
- }
-
- Node conjunct = (disjunction.getNumChildren() == 1) ? disjunction[0] : disjunction;
- builder << conjunct;
- }
- }
+ for (it = used_lemmas.begin(); it != used_lemmas.end(); ++it)
+ {
+ Node lemma = d_cnfProof->getAssertionForClause(it->first);
+ Debug("pf::lemmasUnsatCore") << "Retrieved lemma " << lemma << "\n";
+ lemmas.push_back(lemma);
}
-
- AlwaysAssert(builder.getNumChildren() != 0);
-
- if (builder.getNumChildren() == 1)
- return builder[0];
-
- return builder;
-}
-
-void ProofManager::addAssertion(Expr formula) {
- Debug("proof:pm") << "assert: " << formula << std::endl;
- d_inputFormulas.insert(formula);
- std::ostringstream name;
- name << "A" << d_inputFormulaToName.size();
- d_inputFormulaToName[formula] = name.str();
}
void ProofManager::addCoreAssertion(Expr formula) {
@@ -542,665 +213,4 @@ void ProofManager::addUnsatCore(Expr formula) {
d_outputCoreFormulas.insert(formula);
}
-void ProofManager::addAssertionFilter(const Node& node, const std::string& rewritten) {
- d_assertionFilters[node] = rewritten;
-}
-
-void ProofManager::setLogic(const LogicInfo& logic) {
- d_logic = logic;
-}
-
-LFSCProof::LFSCProof(SmtEngine* smtEngine,
- CoreSatProof* sat,
- LFSCCnfProof* cnf,
- LFSCTheoryProofEngine* theory)
- : d_satProof(sat),
- d_cnfProof(cnf),
- d_theoryProof(theory),
- d_smtEngine(smtEngine)
-{}
-
-void LFSCProof::toStream(std::ostream& out, const ProofLetMap& map) const
-{
- Unreachable();
-}
-
-void collectAtoms(TNode node, std::set<Node>& seen, CnfProof* cnfProof)
-{
- Debug("pf::pm::atoms") << "collectAtoms: Colleting atoms from " << node
- << "\n";
- if (seen.find(node) != seen.end())
- {
- Debug("pf::pm::atoms") << "collectAtoms:\t already seen\n";
- return;
- }
- // if I have a SAT literal for a node, save it, unless this node is a
- // negation, in which case its underlying will be collected downstream
- if (cnfProof->hasLiteral(node) && node.getKind() != kind::NOT)
- {
- Debug("pf::pm::atoms") << "collectAtoms: has SAT literal, save\n";
- seen.insert(node);
- }
- for (unsigned i = 0; i < node.getNumChildren(); ++i)
- {
- Debug("pf::pm::atoms") << push;
- collectAtoms(node[i], seen, cnfProof);
- Debug("pf::pm::atoms") << pop;
- }
-}
-
-void LFSCProof::toStream(std::ostream& out) const
-{
- TimerStat::CodeTimer proofProductionTimer(
- ProofManager::currentPM()->getStats().d_proofProductionTime);
-
- IdToSatClause used_lemmas;
- IdToSatClause used_inputs;
- std::set<Node> atoms;
- NodePairSet rewrites;
- NodeSet used_assertions;
-
- {
- CodeTimer skeletonProofTimer{
- ProofManager::currentPM()->getStats().d_skeletonProofTraceTime};
- Assert(!d_satProof->proofConstructed());
-
- // Here we give our SAT solver a chance to flesh out the resolution proof.
- // It proves bottom from a set of clauses.
- d_satProof->constructProof();
-
- // We ask the SAT solver which clauses are used in that proof.
- // For a resolution proof, these are the leaves of the tree.
- d_satProof->collectClausesUsed(used_inputs, used_lemmas);
-
- IdToSatClause::iterator it2;
- Debug("pf::pm") << std::endl << "Used inputs: " << std::endl;
- for (it2 = used_inputs.begin(); it2 != used_inputs.end(); ++it2)
- {
- Debug("pf::pm") << "\t input = " << *(it2->second) << std::endl;
- }
- Debug("pf::pm") << std::endl;
-
- Debug("pf::pm") << std::endl << "Used lemmas: " << std::endl;
- for (it2 = used_lemmas.begin(); it2 != used_lemmas.end(); ++it2)
- {
- std::vector<Expr> clause_expr;
- for (unsigned i = 0; i < it2->second->size(); ++i)
- {
- prop::SatLiteral lit = (*(it2->second))[i];
- Expr atom = d_cnfProof->getAtom(lit.getSatVariable()).toExpr();
- if (atom.isConst())
- {
- Assert(atom == utils::mkTrue());
- continue;
- }
- Expr expr_lit = lit.isNegated() ? atom.notExpr() : atom;
- clause_expr.push_back(expr_lit);
- }
-
- Debug("pf::pm") << "\t lemma " << it2->first << " = " << *(it2->second)
- << std::endl;
- Debug("pf::pm") << "\t";
- for (unsigned i = 0; i < clause_expr.size(); ++i)
- {
- Debug("pf::pm") << clause_expr[i] << " ";
- }
- Debug("pf::pm") << std::endl;
- }
- Debug("pf::pm") << std::endl;
-
- // collecting assertions that lead to the clauses being asserted
- d_cnfProof->collectAssertionsForClauses(used_inputs, used_assertions);
-
- NodeSet::iterator it3;
- Debug("pf::pm") << std::endl << "Used assertions: " << std::endl;
- for (it3 = used_assertions.begin(); it3 != used_assertions.end(); ++it3)
- Debug("pf::pm") << "\t assertion = " << *it3 << std::endl;
-
- // collects the atoms in the clauses
- d_cnfProof->collectAtomsAndRewritesForLemmas(used_lemmas, atoms, rewrites);
-
- if (!rewrites.empty())
- {
- Debug("pf::pm") << std::endl << "Rewrites used in lemmas: " << std::endl;
- NodePairSet::const_iterator rewriteIt;
- for (rewriteIt = rewrites.begin(); rewriteIt != rewrites.end();
- ++rewriteIt)
- {
- Debug("pf::pm") << "\t" << rewriteIt->first << " --> "
- << rewriteIt->second << std::endl;
- }
- Debug("pf::pm") << std::endl << "Rewrite printing done" << std::endl;
- }
- else
- {
- Debug("pf::pm") << "No rewrites in lemmas found" << std::endl;
- }
-
- // The derived/unrewritten atoms may not have CNF literals required later
- // on. If they don't, add them.
- std::set<Node>::const_iterator it;
- for (it = atoms.begin(); it != atoms.end(); ++it)
- {
- Debug("pf::pm") << "Ensure literal for atom: " << *it << std::endl;
- if (!d_cnfProof->hasLiteral(*it))
- {
- // For arithmetic: these literals are not normalized, causing an error
- // in Arith.
- if (theory::Theory::theoryOf(*it) == theory::THEORY_ARITH)
- {
- d_cnfProof->ensureLiteral(
- *it,
- true); // This disables preregistration with the theory solver.
- }
- else
- {
- d_cnfProof->ensureLiteral(
- *it); // Normal method, with theory solver preregisteration.
- }
- }
- }
-
- // From the clauses, compute the atoms (atomic theory predicates in
- // assertions and lemmas).
- d_cnfProof->collectAtomsForClauses(used_inputs, atoms);
- d_cnfProof->collectAtomsForClauses(used_lemmas, atoms);
-
- // collects the atoms in the assertions
- Debug("pf::pm") << std::endl
- << "LFSCProof::toStream: Colleting atoms from assertions "
- << used_assertions << "\n"
- << push;
- for (TNode used_assertion : used_assertions)
- {
- collectAtoms(used_assertion, atoms, d_cnfProof);
- }
- Debug("pf::pm") << pop;
-
- std::set<Node>::iterator atomIt;
- Debug("pf::pm") << std::endl
- << "Dumping atoms from lemmas, inputs and assertions: "
- << std::endl
- << std::endl;
- for (atomIt = atoms.begin(); atomIt != atoms.end(); ++atomIt)
- {
- Debug("pf::pm") << "\tAtom: " << *atomIt << std::endl;
- }
- }
-
- smt::SmtScope scope(d_smtEngine);
- ProofLetMap globalLetMap;
- std::ostringstream paren;
- {
- CodeTimer declTimer{
- ProofManager::currentPM()->getStats().d_proofDeclarationsTime};
- out << "(check\n";
- paren << ")";
- out << " ;; Declarations\n";
-
- // declare the theory atoms
- Debug("pf::pm") << "LFSCProof::toStream: registering terms:" << std::endl;
- for (std::set<Node>::const_iterator it = atoms.begin(); it != atoms.end(); ++it)
- {
- Debug("pf::pm") << "\tTerm: " << (*it).toExpr() << std::endl;
- d_theoryProof->registerTerm((*it).toExpr());
- }
-
- Debug("pf::pm") << std::endl
- << "Term registration done!" << std::endl
- << std::endl;
-
- Debug("pf::pm") << std::endl
- << "LFSCProof::toStream: starting to print assertions"
- << std::endl;
-
- // print out all the original assertions
- d_theoryProof->registerTermsFromAssertions();
- d_theoryProof->printSortDeclarations(out, paren);
- d_theoryProof->printTermDeclarations(out, paren);
- d_theoryProof->printAssertions(out, paren);
-
- Debug("pf::pm") << std::endl
- << "LFSCProof::toStream: print assertions DONE"
- << std::endl;
-
- out << "(: (holds cln)\n\n";
- paren << ")";
-
- // Have the theory proofs print deferred declarations, e.g. for skolem
- // variables.
- out << " ;; Printing deferred declarations \n\n";
- d_theoryProof->printDeferredDeclarations(out, paren);
-
- out << "\n ;; Printing the global let map";
- d_theoryProof->finalizeBvConflicts(used_lemmas, out);
- ProofManager::getBitVectorProof()->calculateAtomsInBitblastingProof();
- if (options::lfscLetification())
- {
- ProofManager::currentPM()->printGlobalLetMap(
- atoms, globalLetMap, out, paren);
- }
-
- out << " ;; Printing aliasing declarations \n\n";
- d_theoryProof->printAliasingDeclarations(out, paren, globalLetMap);
-
- out << " ;; Rewrites for Lemmas \n";
- d_theoryProof->printLemmaRewrites(rewrites, out, paren);
-
- // print trust that input assertions are their preprocessed form
- printPreprocessedAssertions(used_assertions, out, paren, globalLetMap);
- }
-
- {
- CodeTimer cnfProofTimer{
- ProofManager::currentPM()->getStats().d_cnfProofTime};
- // print mapping between theory atoms and internal SAT variables
- out << ";; Printing mapping from preprocessed assertions into atoms \n";
- d_cnfProof->printAtomMapping(atoms, out, paren, globalLetMap);
-
- Debug("pf::pm") << std::endl
- << "Printing cnf proof for clauses" << std::endl;
-
- IdToSatClause::const_iterator cl_it = used_inputs.begin();
- // print CNF conversion proof for each clause
- for (; cl_it != used_inputs.end(); ++cl_it)
- {
- d_cnfProof->printCnfProofForClause(
- cl_it->first, cl_it->second, out, paren);
- }
- }
-
- {
- CodeTimer theoryLemmaTimer{
- ProofManager::currentPM()->getStats().d_theoryLemmaTime};
- Debug("pf::pm") << std::endl
- << "Printing cnf proof for clauses DONE" << std::endl;
-
- Debug("pf::pm") << "Proof manager: printing theory lemmas" << std::endl;
- d_theoryProof->printTheoryLemmas(used_lemmas, out, paren, globalLetMap);
- Debug("pf::pm") << "Proof manager: printing theory lemmas DONE!"
- << std::endl;
- }
-
- {
- CodeTimer finalProofTimer{
- ProofManager::currentPM()->getStats().d_finalProofTime};
- out << ";; Printing final unsat proof \n";
- if (options::bitblastMode() == options::BitblastMode::EAGER
- && ProofManager::getBitVectorProof())
- {
- ProofManager::getBitVectorProof()->printEmptyClauseProof(out, paren);
- }
- else
- {
- // print actual resolution proof
- proof::LFSCProofPrinter::printResolutions(d_satProof, out, paren);
- proof::LFSCProofPrinter::printResolutionEmptyClause(
- d_satProof, out, paren);
- }
- }
-
- out << paren.str();
- out << "\n;;\n";
-}
-
-void LFSCProof::printPreprocessedAssertions(const NodeSet& assertions,
- std::ostream& os,
- std::ostream& paren,
- ProofLetMap& globalLetMap) const
-{
- os << "\n ;; In the preprocessor we trust \n";
- NodeSet::const_iterator it = assertions.begin();
- NodeSet::const_iterator end = assertions.end();
-
- Debug("pf::pm") << "LFSCProof::printPreprocessedAssertions starting" << std::endl;
-
- if (options::fewerPreprocessingHoles()) {
- // Check for assertions that did not get rewritten, and update the printing filter.
- checkUnrewrittenAssertion(assertions);
-
- // For the remaining assertions, bind them to input assertions.
- for (; it != end; ++it) {
- // Rewrite preprocessing step if it cannot be eliminated
- if (!ProofManager::currentPM()->have_input_assertion((*it).toExpr())) {
- os << "(th_let_pf _ (trust_f (iff ";
-
- Expr inputAssertion;
-
- if (((*it).isConst() && *it == NodeManager::currentNM()->mkConst<bool>(true)) ||
- ((*it).getKind() == kind::NOT && (*it)[0] == NodeManager::currentNM()->mkConst<bool>(false))) {
- inputAssertion = NodeManager::currentNM()->mkConst<bool>(true).toExpr();
- } else {
- // Figure out which input assertion led to this assertion
- ExprSet inputAssertions;
- ProofManager::currentPM()->traceDeps(*it, &inputAssertions);
-
- Debug("pf::pm") << "Original assertions for " << *it << " are: " << std::endl;
-
- ProofManager::assertions_iterator assertionIt;
- for (assertionIt = inputAssertions.begin(); assertionIt != inputAssertions.end(); ++assertionIt) {
- Debug("pf::pm") << "\t" << *assertionIt << std::endl;
- }
-
- if (inputAssertions.size() == 0) {
- Debug("pf::pm") << "LFSCProof::printPreprocessedAssertions: Count NOT find the assertion that caused this PA. Picking an arbitrary one..." << std::endl;
- // For now just use the first assertion...
- inputAssertion = *(ProofManager::currentPM()->begin_assertions());
- } else {
- if (inputAssertions.size() != 1) {
- Debug("pf::pm") << "LFSCProof::printPreprocessedAssertions: Attention: more than one original assertion was found. Picking just one." << std::endl;
- }
- inputAssertion = *inputAssertions.begin();
- }
- }
-
- if (!ProofManager::currentPM()->have_input_assertion(inputAssertion)) {
- // The thing returned by traceDeps does not appear in the input assertions...
- Debug("pf::pm") << "LFSCProof::printPreprocessedAssertions: Count NOT find the assertion that caused this PA. Picking an arbitrary one..." << std::endl;
- // For now just use the first assertion...
- inputAssertion = *(ProofManager::currentPM()->begin_assertions());
- }
-
- Debug("pf::pm") << "Original assertion for " << *it
- << " is: "
- << inputAssertion
- << ", AKA "
- << ProofManager::currentPM()->getInputFormulaName(inputAssertion)
- << std::endl;
-
- ProofManager::currentPM()->getTheoryProofEngine()->printTheoryTerm(inputAssertion, os, globalLetMap);
- os << " ";
- ProofManager::currentPM()->printTrustedTerm(*it, os, globalLetMap);
- os << "))";
- os << "(\\ "<< ProofManager::getPreprocessedAssertionName(*it, "") << "\n";
- paren << "))";
-
- std::ostringstream rewritten;
-
- rewritten << "(or_elim_1 _ _ ";
- rewritten << "(not_not_intro _ ";
- rewritten << ProofManager::currentPM()->getInputFormulaName(inputAssertion);
- rewritten << ") (iff_elim_1 _ _ ";
- rewritten << ProofManager::getPreprocessedAssertionName(*it, "");
- rewritten << "))";
-
- ProofManager::currentPM()->addAssertionFilter(*it, rewritten.str());
- }
- }
- } else {
- for (; it != end; ++it) {
- os << "(th_let_pf _ ";
-
- //TODO
- os << "(trust_f ";
- ProofManager::currentPM()->printTrustedTerm(*it, os, globalLetMap);
- os << ") ";
-
- os << "(\\ "<< ProofManager::getPreprocessedAssertionName(*it, "") << "\n";
- paren << "))";
- }
- }
-
- os << "\n";
-}
-
-void LFSCProof::checkUnrewrittenAssertion(const NodeSet& rewrites) const
-{
- Debug("pf::pm") << "LFSCProof::checkUnrewrittenAssertion starting" << std::endl;
-
- NodeSet::const_iterator rewrite;
- for (rewrite = rewrites.begin(); rewrite != rewrites.end(); ++rewrite) {
- Debug("pf::pm") << "LFSCProof::checkUnrewrittenAssertion: handling " << *rewrite << std::endl;
- if (ProofManager::currentPM()->have_input_assertion((*rewrite).toExpr())) {
- Assert(
- ProofManager::currentPM()->have_input_assertion((*rewrite).toExpr()));
- Debug("pf::pm") << "LFSCProof::checkUnrewrittenAssertion: this assertion was NOT rewritten!" << std::endl
- << "\tAdding filter: "
- << ProofManager::getPreprocessedAssertionName(*rewrite, "")
- << " --> "
- << ProofManager::currentPM()->getInputFormulaName((*rewrite).toExpr())
- << std::endl;
- ProofManager::currentPM()->addAssertionFilter(*rewrite,
- ProofManager::currentPM()->getInputFormulaName((*rewrite).toExpr()));
- } else {
- Debug("pf::pm") << "LFSCProof::checkUnrewrittenAssertion: this assertion WAS rewritten! " << *rewrite << std::endl;
- }
- }
-}
-
-//---from Morgan---
-
-bool ProofManager::hasOp(TNode n) const {
- return d_bops.find(n) != d_bops.end();
-}
-
-Node ProofManager::lookupOp(TNode n) const {
- std::map<Node, Node>::const_iterator i = d_bops.find(n);
- Assert(i != d_bops.end());
- return (*i).second;
-}
-
-Node ProofManager::mkOp(TNode n) {
- Trace("mgd-pm-mkop") << "MkOp : " << n << " " << n.getKind() << std::endl;
- if(n.getKind() != kind::BUILTIN) {
- return n;
- }
-
- Node& op = d_ops[n];
- if(op.isNull()) {
- Assert((n.getConst<Kind>() == kind::SELECT)
- || (n.getConst<Kind>() == kind::STORE));
-
- Debug("mgd-pm-mkop") << "making an op for " << n << "\n";
-
- std::stringstream ss;
- ss << n;
- std::string s = ss.str();
- Debug("mgd-pm-mkop") << " : " << s << std::endl;
- std::vector<TypeNode> v;
- v.push_back(NodeManager::currentNM()->integerType());
- if(n.getConst<Kind>() == kind::SELECT) {
- v.push_back(NodeManager::currentNM()->integerType());
- v.push_back(NodeManager::currentNM()->integerType());
- } else if(n.getConst<Kind>() == kind::STORE) {
- v.push_back(NodeManager::currentNM()->integerType());
- v.push_back(NodeManager::currentNM()->integerType());
- v.push_back(NodeManager::currentNM()->integerType());
- }
- TypeNode type = NodeManager::currentNM()->mkFunctionType(v);
- Debug("mgd-pm-mkop") << "typenode is: " << type << "\n";
- op = NodeManager::currentNM()->mkSkolem(s, type, " ignore", NodeManager::SKOLEM_NO_NOTIFY);
- d_bops[op] = n;
- }
- Debug("mgd-pm-mkop") << "returning the op: " << op << "\n";
- return op;
-}
-//---end from Morgan---
-
-bool ProofManager::wasPrinted(const Type& type) const {
- return d_printedTypes.find(type) != d_printedTypes.end();
-}
-
-void ProofManager::markPrinted(const Type& type) {
- d_printedTypes.insert(type);
-}
-
-void ProofManager::addRewriteFilter(const std::string &original, const std::string &substitute) {
- d_rewriteFilters[original] = substitute;
-}
-
-bool ProofManager::haveRewriteFilter(TNode lit) {
- std::string litName = getLitName(currentPM()->d_cnfProof->getLiteral(lit));
- return d_rewriteFilters.find(litName) != d_rewriteFilters.end();
-}
-
-void ProofManager::clearRewriteFilters() {
- d_rewriteFilters.clear();
-}
-
-std::ostream& operator<<(std::ostream& out, CVC4::ProofRule k) {
- switch(k) {
- case RULE_GIVEN:
- out << "RULE_GIVEN";
- break;
- case RULE_DERIVED:
- out << "RULE_DERIVED";
- break;
- case RULE_RECONSTRUCT:
- out << "RULE_RECONSTRUCT";
- break;
- case RULE_TRUST:
- out << "RULE_TRUST";
- break;
- case RULE_INVALID:
- out << "RULE_INVALID";
- break;
- case RULE_CONFLICT:
- out << "RULE_CONFLICT";
- break;
- case RULE_TSEITIN:
- out << "RULE_TSEITIN";
- break;
- case RULE_SPLIT:
- out << "RULE_SPLIT";
- break;
- case RULE_ARRAYS_EXT:
- out << "RULE_ARRAYS";
- break;
- case RULE_ARRAYS_ROW:
- out << "RULE_ARRAYS";
- break;
- default:
- out << "ProofRule Unknown! [" << unsigned(k) << "]";
- }
-
- return out;
-}
-
-void ProofManager::registerRewrite(unsigned ruleId, Node original, Node result){
- Assert(currentPM()->d_theoryProof != NULL);
- currentPM()->d_rewriteLog.push_back(RewriteLogEntry(ruleId, original, result));
-}
-
-void ProofManager::clearRewriteLog() {
- Assert(currentPM()->d_theoryProof != NULL);
- currentPM()->d_rewriteLog.clear();
-}
-
-std::vector<RewriteLogEntry> ProofManager::getRewriteLog() {
- return currentPM()->d_rewriteLog;
-}
-
-void ProofManager::dumpRewriteLog() const {
- Debug("pf::rr") << "Dumpign rewrite log:" << std::endl;
-
- for (unsigned i = 0; i < d_rewriteLog.size(); ++i) {
- Debug("pf::rr") << "\tRule " << d_rewriteLog[i].getRuleId()
- << ": "
- << d_rewriteLog[i].getOriginal()
- << " --> "
- << d_rewriteLog[i].getResult() << std::endl;
- }
-}
-
-void bind(Expr term, ProofLetMap& map, Bindings& letOrder) {
- ProofLetMap::iterator it = map.find(term);
- if (it != map.end())
- return;
-
- for (unsigned i = 0; i < term.getNumChildren(); ++i)
- bind(term[i], map, letOrder);
-
- // Special case: chain operators. If we have and(a,b,c), it will be prineted as and(a,and(b,c)).
- // The subterm and(b,c) may repeat elsewhere, so we need to bind it, too.
- Kind k = term.getKind();
- if (((k == kind::OR) || (k == kind::AND)) && term.getNumChildren() > 2) {
- Node currentExpression = term[term.getNumChildren() - 1];
- for (int i = term.getNumChildren() - 2; i >= 0; --i) {
- NodeBuilder<> builder(k);
- builder << term[i];
- builder << currentExpression.toExpr();
- currentExpression = builder;
- bind(currentExpression.toExpr(), map, letOrder);
- }
- } else {
- unsigned newId = ProofLetCount::newId();
- ProofLetCount letCount(newId);
- map[term] = letCount;
- letOrder.push_back(LetOrderElement(term, newId));
- }
-}
-
-void ProofManager::printGlobalLetMap(std::set<Node>& atoms,
- ProofLetMap& letMap,
- std::ostream& out,
- std::ostringstream& paren) {
- Bindings letOrder;
- std::set<Node>::const_iterator atom;
- for (atom = atoms.begin(); atom != atoms.end(); ++atom) {
- bind(atom->toExpr(), letMap, letOrder);
- }
-
- // TODO: give each theory a chance to add atoms. For now, just query BV directly...
- const std::set<Node>* additionalAtoms = ProofManager::getBitVectorProof()->getAtomsInBitblastingProof();
- for (atom = additionalAtoms->begin(); atom != additionalAtoms->end(); ++atom) {
- bind(atom->toExpr(), letMap, letOrder);
- }
-
- for (unsigned i = 0; i < letOrder.size(); ++i) {
- Expr currentExpr = letOrder[i].expr;
- unsigned letId = letOrder[i].id;
- ProofLetMap::iterator it = letMap.find(currentExpr);
- Assert(it != letMap.end());
- out << "\n(@ let" << letId << " ";
- d_theoryProof->printBoundTerm(currentExpr, out, letMap);
- paren << ")";
- it->second.increment();
- }
-
- out << std::endl << std::endl;
-}
-
-void ProofManager::ensureLiteral(Node node) {
- d_cnfProof->ensureLiteral(node);
-}
-void ProofManager::printTrustedTerm(Node term,
- std::ostream& os,
- ProofLetMap& globalLetMap)
-{
- TheoryProofEngine* tpe = ProofManager::currentPM()->getTheoryProofEngine();
- if (tpe->printsAsBool(term)) os << "(p_app ";
- tpe->printTheoryTerm(term.toExpr(), os, globalLetMap);
- if (tpe->printsAsBool(term)) os << ")";
-}
-
-ProofManager::ProofManagerStatistics::ProofManagerStatistics()
- : d_proofProductionTime("proof::ProofManager::proofProductionTime"),
- d_theoryLemmaTime(
- "proof::ProofManager::proofProduction::theoryLemmaTime"),
- d_skeletonProofTraceTime(
- "proof::ProofManager::proofProduction::skeletonProofTraceTime"),
- d_proofDeclarationsTime(
- "proof::ProofManager::proofProduction::proofDeclarationsTime"),
- d_cnfProofTime("proof::ProofManager::proofProduction::cnfProofTime"),
- d_finalProofTime("proof::ProofManager::proofProduction::finalProofTime")
-{
- smtStatisticsRegistry()->registerStat(&d_proofProductionTime);
- smtStatisticsRegistry()->registerStat(&d_theoryLemmaTime);
- smtStatisticsRegistry()->registerStat(&d_skeletonProofTraceTime);
- smtStatisticsRegistry()->registerStat(&d_proofDeclarationsTime);
- smtStatisticsRegistry()->registerStat(&d_cnfProofTime);
- smtStatisticsRegistry()->registerStat(&d_finalProofTime);
-}
-
-ProofManager::ProofManagerStatistics::~ProofManagerStatistics()
-{
- smtStatisticsRegistry()->unregisterStat(&d_proofProductionTime);
- smtStatisticsRegistry()->unregisterStat(&d_theoryLemmaTime);
- smtStatisticsRegistry()->unregisterStat(&d_skeletonProofTraceTime);
- smtStatisticsRegistry()->unregisterStat(&d_proofDeclarationsTime);
- smtStatisticsRegistry()->unregisterStat(&d_cnfProofTime);
- smtStatisticsRegistry()->unregisterStat(&d_finalProofTime);
-}
-
} /* CVC4 namespace */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback