summaryrefslogtreecommitdiff
path: root/src/proof/er/er_proof.cpp
diff options
context:
space:
mode:
authorAlex Ozdemir <aozdemir@hmc.edu>2019-06-05 12:16:46 -0700
committerAndres Noetzli <noetzli@stanford.edu>2019-06-05 12:16:46 -0700
commit9af5e9653582a18b1871dfc3774ab50dd24463ce (patch)
tree9bbe5cd5708dbd3475626cabd4d2c9711f0ac133 /src/proof/er/er_proof.cpp
parentc587235d29d2e3e1cd52a9f76dde8f58c89ae37e (diff)
DRAT-Optimization (#2971)
This commit enables DRAT-optimization, which consists of two sub-processes: 1. removing unnecessary instructions from DRAT-proofs and 2. not proving clauses which are not needed by DRAT proofs. These changes have the effect of dramatically shortening some some bit-vector proofs. Specifically, proofs using lemmas in the ER, DRAT, and LRAT formats, since proofs in any of these formats are derived from a (now optimized!) DRAT proof produced by CryptoMiniSat. What follows is a description of the main parts of this PR: ## DRAT Optimization The DRAT-optimization is done by `drat-trim`, which is bundled with `drat2er`. The (new) function `ClausalBitVectorProof::optimizeDratProof` is our interface to the optimization machinery, and most of the new logic in this PR is in that function. ## CNF Representation The ability to not prove unused clauses requires a slight architectural change as well. In particular, we need to be able to describe **which** subset of the original clause set actually needs to be proved. To facilitate this, when the clause set for CryptoMiniSat is first formed it is represented as a (a) map from clause indices to clauses and (b) a list of indices. Then, when the CNF is optimized, we temporarily store a new list of the clauses in the optimized formula. This change in representation requires a number of small tweaks throughout the code. ## Small Fixes to Signatures When we decided to check and accept two different kinds of DRAT, some of our DRAT-checking broke. In particular, when supporting one kind of DRAT, it is okay to `fail` (crash) when a proof fails to check. If you're supporting two kinds of DRAT, crashing in response to the first checker rejecting the proof denies the second checker an opportunity to check the proof. This PR tweaks the signatures slightly (and soundly!) to do something else instead of `fail`ing.
Diffstat (limited to 'src/proof/er/er_proof.cpp')
-rw-r--r--src/proof/er/er_proof.cpp39
1 files changed, 19 insertions, 20 deletions
diff --git a/src/proof/er/er_proof.cpp b/src/proof/er/er_proof.cpp
index 22903c3c9..9160546f9 100644
--- a/src/proof/er/er_proof.cpp
+++ b/src/proof/er/er_proof.cpp
@@ -31,7 +31,7 @@
#include "base/cvc4_assert.h"
#include "base/map_util.h"
-#include "proof/dimacs_printer.h"
+#include "proof/dimacs.h"
#include "proof/lfsc_proof_printer.h"
#include "proof/proof_manager.h"
@@ -80,8 +80,10 @@ TraceCheckProof TraceCheckProof::fromText(std::istream& in)
return pf;
}
-ErProof ErProof::fromBinaryDratProof(const ClauseUseRecord& usedClauses,
- const std::string& dratBinary)
+ErProof ErProof::fromBinaryDratProof(
+ const std::unordered_map<ClauseId, prop::SatClause>& clauses,
+ const std::vector<ClauseId>& usedIds,
+ const std::string& dratBinary)
{
std::ostringstream cmd;
char formulaFilename[] = "/tmp/cvc4-dimacs-XXXXXX";
@@ -101,7 +103,7 @@ ErProof ErProof::fromBinaryDratProof(const ClauseUseRecord& usedClauses,
// Write the formula
std::ofstream formStream(formulaFilename);
- printDimacs(formStream, usedClauses);
+ printDimacs(formStream, clauses, usedIds);
formStream.close();
// Write the (binary) DRAT proof
@@ -126,7 +128,8 @@ ErProof ErProof::fromBinaryDratProof(const ClauseUseRecord& usedClauses,
// Parse the resulting TRACECHECK proof into an ER proof.
std::ifstream tracecheckStream(tracecheckFilename);
- ErProof proof(usedClauses, TraceCheckProof::fromText(tracecheckStream));
+ TraceCheckProof pf = TraceCheckProof::fromText(tracecheckStream);
+ ErProof proof(clauses, usedIds, std::move(pf));
tracecheckStream.close();
remove(formulaFilename);
@@ -136,17 +139,21 @@ ErProof ErProof::fromBinaryDratProof(const ClauseUseRecord& usedClauses,
return proof;
}
-ErProof::ErProof(const ClauseUseRecord& usedClauses,
+ErProof::ErProof(const std::unordered_map<ClauseId, prop::SatClause>& clauses,
+ const std::vector<ClauseId>& usedIds,
TraceCheckProof&& tracecheck)
: d_inputClauseIds(), d_definitions(), d_tracecheck(tracecheck)
{
// Step zero, save input clause Ids for future printing
- std::transform(usedClauses.begin(),
- usedClauses.end(),
- std::back_inserter(d_inputClauseIds),
- [](const std::pair<ClauseId, prop::SatClause>& pair) {
- return pair.first;
- });
+ d_inputClauseIds = usedIds;
+
+ // Make a list of (idx, clause pairs), the used ones.
+ std::vector<std::pair<ClauseId, prop::SatClause>> usedClauses;
+ std::transform(
+ usedIds.begin(),
+ usedIds.end(),
+ std::back_inserter(usedClauses),
+ [&](const ClauseId& i) { return make_pair(i, clauses.at(i)); });
// Step one, verify the formula starts the proof
if (Configuration::isAssertionBuild())
@@ -162,14 +169,6 @@ ErProof::ErProof(const ClauseUseRecord& usedClauses,
originalClause{usedClauses[i].second.begin(),
usedClauses[i].second.end()};
Assert(traceCheckClause == originalClause);
- Assert(d_tracecheck.d_lines[i].d_idx = i + 1);
- Assert(d_tracecheck.d_lines[i].d_chain.size() == 0);
- Assert(d_tracecheck.d_lines[i].d_clause.size()
- == usedClauses[i].second.size());
- for (size_t j = 0, m = usedClauses[i].second.size(); j < m; ++j)
- {
- Assert(usedClauses[i].second[j] == d_tracecheck.d_lines[i].d_clause[j]);
- }
}
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback