summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndres Noetzli <andres.noetzli@gmail.com>2019-06-11 16:25:09 -0700
committerAndres Noetzli <andres.noetzli@gmail.com>2019-06-11 16:25:09 -0700
commita6f694c852b22789a1cca9116ba5de4b6663ccce (patch)
tree6af041a840968d2922555efba4d3a65e0d12b0ee /src
parentc86d1f39c9d2a78eb6c86ea9bcbfaed10d97ac18 (diff)
parent6b01e8740111e69219e5d733e1123955f8cd2ea7 (diff)
Merge branch 'master' into fixBetterSkolems
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/bindings/java/CMakeLists.txt6
-rw-r--r--src/expr/node_algorithm.cpp32
-rw-r--r--src/expr/node_algorithm.h8
-rw-r--r--src/expr/node_builder.h4
-rw-r--r--src/printer/dagification_visitor.cpp54
-rw-r--r--src/printer/dagification_visitor.h7
-rw-r--r--src/proof/clausal_bitvector_proof.cpp183
-rw-r--r--src/proof/clausal_bitvector_proof.h11
-rw-r--r--src/proof/dimacs.cpp (renamed from src/proof/dimacs_printer.cpp)63
-rw-r--r--src/proof/dimacs.h (renamed from src/proof/dimacs_printer.h)19
-rw-r--r--src/proof/er/er_proof.cpp39
-rw-r--r--src/proof/er/er_proof.h21
-rw-r--r--src/proof/lrat/lrat_proof.cpp19
-rw-r--r--src/proof/lrat/lrat_proof.h10
-rw-r--r--src/smt/smt_engine.cpp19
-rw-r--r--src/smt/smt_engine.h5
-rw-r--r--src/smt/smt_engine.i3
-rw-r--r--src/theory/fp/fp_converter.cpp6
-rw-r--r--src/theory/logic_info.cpp21
-rw-r--r--src/util/floatingpoint.cpp6
21 files changed, 405 insertions, 135 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index cff31dbcd..011ba6ab5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -137,8 +137,8 @@ libcvc4_add_sources(
proof/clause_id.h
proof/cnf_proof.cpp
proof/cnf_proof.h
- proof/dimacs_printer.cpp
- proof/dimacs_printer.h
+ proof/dimacs.cpp
+ proof/dimacs.h
proof/drat/drat_proof.cpp
proof/drat/drat_proof.h
proof/er/er_proof.cpp
diff --git a/src/bindings/java/CMakeLists.txt b/src/bindings/java/CMakeLists.txt
index 7b7d93f1d..b1631f369 100644
--- a/src/bindings/java/CMakeLists.txt
+++ b/src/bindings/java/CMakeLists.txt
@@ -131,6 +131,7 @@ set(gen_java_files
${CMAKE_CURRENT_BINARY_DIR}/LastExceptionBuffer.java
${CMAKE_CURRENT_BINARY_DIR}/LogicException.java
${CMAKE_CURRENT_BINARY_DIR}/LogicInfo.java
+ ${CMAKE_CURRENT_BINARY_DIR}/Map_ExprExpr.java
${CMAKE_CURRENT_BINARY_DIR}/ModalException.java
${CMAKE_CURRENT_BINARY_DIR}/OptionException.java
${CMAKE_CURRENT_BINARY_DIR}/Options.java
@@ -165,7 +166,6 @@ set(gen_java_files
${CMAKE_CURRENT_BINARY_DIR}/SExpr.java
${CMAKE_CURRENT_BINARY_DIR}/SExprKeyword.java
${CMAKE_CURRENT_BINARY_DIR}/SExprType.java
- ${CMAKE_CURRENT_BINARY_DIR}/Statistic.java
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_CVC4__Model.java
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_CVC4__Printer.java
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_CVC4__api__Solver.java
@@ -178,7 +178,6 @@ set(gen_java_files
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_mpq_class.java
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_mpz_class.java
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_std__istream.java
- ${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_std__mapT_CVC4__Expr_CVC4__Expr_t.java
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_std__ostream.java
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_std__shared_ptrT_CVC4__SygusPrintCallback_t.java
${CMAKE_CURRENT_BINARY_DIR}/SWIGTYPE_p_std__string.java
@@ -201,16 +200,17 @@ set(gen_java_files
${CMAKE_CURRENT_BINARY_DIR}/SmtEngine.java
${CMAKE_CURRENT_BINARY_DIR}/SortConstructorType.java
${CMAKE_CURRENT_BINARY_DIR}/SortType.java
+ ${CMAKE_CURRENT_BINARY_DIR}/Statistic.java
${CMAKE_CURRENT_BINARY_DIR}/Statistics.java
${CMAKE_CURRENT_BINARY_DIR}/StatisticsBase.java
${CMAKE_CURRENT_BINARY_DIR}/StringType.java
${CMAKE_CURRENT_BINARY_DIR}/SygusConstraintCommand.java
- ${CMAKE_CURRENT_BINARY_DIR}/SynthFunCommand.java
${CMAKE_CURRENT_BINARY_DIR}/SygusGTerm.java
${CMAKE_CURRENT_BINARY_DIR}/SygusInvConstraintCommand.java
${CMAKE_CURRENT_BINARY_DIR}/SygusPrintCallback.java
${CMAKE_CURRENT_BINARY_DIR}/SymbolTable.java
${CMAKE_CURRENT_BINARY_DIR}/SymbolType.java
+ ${CMAKE_CURRENT_BINARY_DIR}/SynthFunCommand.java
${CMAKE_CURRENT_BINARY_DIR}/TesterType.java
${CMAKE_CURRENT_BINARY_DIR}/TheoryId.java
${CMAKE_CURRENT_BINARY_DIR}/Timer.java
diff --git a/src/expr/node_algorithm.cpp b/src/expr/node_algorithm.cpp
index 25ffb0778..841f9ea28 100644
--- a/src/expr/node_algorithm.cpp
+++ b/src/expr/node_algorithm.cpp
@@ -236,6 +236,38 @@ bool getFreeVariables(TNode n,
return !fvs.empty();
}
+bool getVariables(TNode n, std::unordered_set<TNode, TNodeHashFunction>& vs)
+{
+ std::unordered_set<TNode, TNodeHashFunction> visited;
+ std::vector<TNode> visit;
+ TNode cur;
+ visit.push_back(n);
+ do
+ {
+ cur = visit.back();
+ visit.pop_back();
+ std::unordered_set<TNode, TNodeHashFunction>::iterator itv =
+ visited.find(cur);
+ if (itv == visited.end())
+ {
+ if (cur.isVar())
+ {
+ vs.insert(cur);
+ }
+ else
+ {
+ for (const TNode& cn : cur)
+ {
+ visit.push_back(cn);
+ }
+ }
+ visited.insert(cur);
+ }
+ } while (!visit.empty());
+
+ return !vs.empty();
+}
+
void getSymbols(TNode n, std::unordered_set<Node, NodeHashFunction>& syms)
{
std::unordered_set<TNode, TNodeHashFunction> visited;
diff --git a/src/expr/node_algorithm.h b/src/expr/node_algorithm.h
index 656f162ae..727f5ba75 100644
--- a/src/expr/node_algorithm.h
+++ b/src/expr/node_algorithm.h
@@ -73,6 +73,14 @@ bool getFreeVariables(TNode n,
bool computeFv = true);
/**
+ * Get all variables in n.
+ * @param n The node under investigation
+ * @param vs The set which free variables are added to
+ * @return true iff this node contains a free variable.
+ */
+bool getVariables(TNode n, std::unordered_set<TNode, TNodeHashFunction>& vs);
+
+/**
* For term n, this function collects the symbols that occur as a subterms
* of n. A symbol is a variable that does not have kind BOUND_VARIABLE.
* @param n The node under investigation
diff --git a/src/expr/node_builder.h b/src/expr/node_builder.h
index 9128bc190..4558f3720 100644
--- a/src/expr/node_builder.h
+++ b/src/expr/node_builder.h
@@ -772,8 +772,8 @@ void NodeBuilder<nchild_thresh>::clear(Kind k) {
template <unsigned nchild_thresh>
void NodeBuilder<nchild_thresh>::realloc(size_t toSize) {
- Assert( toSize > d_nvMaxChildren,
- "attempt to realloc() a NodeBuilder to a smaller/equal size!" );
+ AlwaysAssert(toSize > d_nvMaxChildren,
+ "attempt to realloc() a NodeBuilder to a smaller/equal size!");
Assert( toSize < (1lu << CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN),
"attempt to realloc() a NodeBuilder to size %u (beyond hard limit of %u)",
toSize, (1lu << CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN) - 1 );
diff --git a/src/printer/dagification_visitor.cpp b/src/printer/dagification_visitor.cpp
index cf5f35457..a024c97a7 100644
--- a/src/printer/dagification_visitor.cpp
+++ b/src/printer/dagification_visitor.cpp
@@ -17,6 +17,8 @@
#include "printer/dagification_visitor.h"
#include "context/context.h"
+#include "expr/node_algorithm.h"
+#include "expr/node_manager_attributes.h"
#include "theory/substitutions.h"
#include <sstream>
@@ -24,18 +26,20 @@
namespace CVC4 {
namespace printer {
-DagificationVisitor::DagificationVisitor(unsigned threshold, std::string letVarPrefix) :
- d_threshold(threshold),
- d_letVarPrefix(letVarPrefix),
- d_nodeCount(),
- d_top(),
- d_context(new context::Context()),
- d_substitutions(new theory::SubstitutionMap(d_context)),
- d_letVar(0),
- d_done(false),
- d_uniqueParent(),
- d_substNodes() {
-
+DagificationVisitor::DagificationVisitor(unsigned threshold,
+ std::string letVarPrefix)
+ : d_threshold(threshold),
+ d_letVarPrefix(letVarPrefix),
+ d_nodeCount(),
+ d_reservedLetNames(),
+ d_top(),
+ d_context(new context::Context()),
+ d_substitutions(new theory::SubstitutionMap(d_context)),
+ d_letVar(0),
+ d_done(false),
+ d_uniqueParent(),
+ d_substNodes()
+{
// 0 doesn't make sense
AlwaysAssertArgument(threshold > 0, threshold);
}
@@ -51,8 +55,28 @@ bool DagificationVisitor::alreadyVisited(TNode current, TNode parent) {
{
// for quantifiers, we visit them but we don't recurse on them
visit(current, parent);
+
+ // search for variables that start with the let prefix
+ std::unordered_set<TNode, TNodeHashFunction> vs;
+ expr::getVariables(current, vs);
+ for (const TNode v : vs)
+ {
+ const std::string name = v.getAttribute(expr::VarNameAttr());
+ if (name.compare(0, d_letVarPrefix.size(), d_letVarPrefix) == 0)
+ {
+ d_reservedLetNames.insert(name);
+ }
+ }
return true;
}
+ else if (current.isVar())
+ {
+ const std::string name = current.getAttribute(expr::VarNameAttr());
+ if (name.compare(0, d_letVarPrefix.size(), d_letVarPrefix) == 0)
+ {
+ d_reservedLetNames.insert(name);
+ }
+ }
// don't visit variables, constants, or those exprs that we've
// already seen more than the threshold: if we've increased
// the count beyond the threshold already, we've done the same
@@ -137,7 +161,11 @@ void DagificationVisitor::done(TNode node) {
// construct the let binder
std::stringstream ss;
- ss << d_letVarPrefix << d_letVar++;
+ do
+ {
+ ss.str("");
+ ss << d_letVarPrefix << d_letVar++;
+ } while (d_reservedLetNames.find(ss.str()) != d_reservedLetNames.end());
Node letvar = NodeManager::currentNM()->mkSkolem(ss.str(), (*i).getType(), "dagification", NodeManager::SKOLEM_NO_NOTIFY | NodeManager::SKOLEM_EXACT_NAME);
// apply previous substitutions to the rhs, enabling cascading LETs
diff --git a/src/printer/dagification_visitor.h b/src/printer/dagification_visitor.h
index 18f31e662..6df5f32b4 100644
--- a/src/printer/dagification_visitor.h
+++ b/src/printer/dagification_visitor.h
@@ -21,6 +21,7 @@
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "expr/node.h"
@@ -69,6 +70,12 @@ class DagificationVisitor {
std::unordered_map<TNode, unsigned, TNodeHashFunction> d_nodeCount;
/**
+ * The set of variable names with the let prefix that appear in the
+ * expression.
+ */
+ std::unordered_set<std::string> d_reservedLetNames;
+
+ /**
* The top-most node we are visiting.
*/
TNode d_top;
diff --git a/src/proof/clausal_bitvector_proof.cpp b/src/proof/clausal_bitvector_proof.cpp
index eed295b1a..07589fd07 100644
--- a/src/proof/clausal_bitvector_proof.cpp
+++ b/src/proof/clausal_bitvector_proof.cpp
@@ -17,24 +17,35 @@
#include "cvc4_private.h"
#include <algorithm>
+#include <iostream>
#include <iterator>
-#include <set>
+#include <unordered_set>
#include "options/bv_options.h"
#include "proof/clausal_bitvector_proof.h"
+#include "proof/dimacs.h"
#include "proof/drat/drat_proof.h"
#include "proof/er/er_proof.h"
#include "proof/lfsc_proof_printer.h"
#include "proof/lrat/lrat_proof.h"
#include "theory/bv/theory_bv.h"
+#if CVC4_USE_DRAT2ER
+#include "drat2er_options.h"
+#include "drat_trim_interface.h"
+#endif
+
namespace CVC4 {
namespace proof {
ClausalBitVectorProof::ClausalBitVectorProof(theory::bv::TheoryBV* bv,
TheoryProofEngine* proofEngine)
- : BitVectorProof(bv, proofEngine), d_usedClauses(), d_binaryDratProof()
+ : BitVectorProof(bv, proofEngine),
+ d_clauses(),
+ d_originalClauseIndices(),
+ d_binaryDratProof(),
+ d_coreClauseIndices()
{
}
@@ -69,33 +80,151 @@ void ClausalBitVectorProof::initCnfProof(prop::CnfStream* cnfStream,
void ClausalBitVectorProof::registerUsedClause(ClauseId id,
prop::SatClause& clause)
{
- d_usedClauses.emplace_back(id, clause);
+ d_clauses.emplace(id, clause);
+ d_originalClauseIndices.push_back(id);
};
void ClausalBitVectorProof::calculateAtomsInBitblastingProof()
{
+ optimizeDratProof();
+
// Debug dump of DRAT Proof
if (Debug.isOn("bv::clausal"))
{
std::string serializedDratProof = d_binaryDratProof.str();
+ Debug("bv::clausal") << "option: " << options::bvOptimizeSatProof()
+ << std::endl;
Debug("bv::clausal") << "binary DRAT proof byte count: "
<< serializedDratProof.size() << std::endl;
- Debug("bv::clausal") << "Parsing DRAT proof ... " << std::endl;
- drat::DratProof dratProof =
- drat::DratProof::fromBinary(serializedDratProof);
-
- Debug("bv::clausal") << "Printing DRAT proof ... " << std::endl;
- dratProof.outputAsText(Debug("bv::clausal"));
+ Debug("bv::clausal") << "clause count: " << d_coreClauseIndices.size()
+ << std::endl;
}
// Empty any old record of which atoms were used
d_atomsInBitblastingProof.clear();
+ Assert(d_atomsInBitblastingProof.size() == 0);
// For each used clause, ask the CNF proof which atoms are used in it
- for (const auto& usedIndexAndClause : d_usedClauses)
+ for (const ClauseId usedIdx : d_coreClauseIndices)
{
- d_cnfProof->collectAtoms(&usedIndexAndClause.second,
- d_atomsInBitblastingProof);
+ d_cnfProof->collectAtoms(&d_clauses.at(usedIdx), d_atomsInBitblastingProof);
+ }
+}
+
+void ClausalBitVectorProof::optimizeDratProof()
+{
+ if (options::bvOptimizeSatProof()
+ == theory::bv::BvOptimizeSatProof::BITVECTOR_OPTIMIZE_SAT_PROOF_PROOF
+ || options::bvOptimizeSatProof()
+ == theory::bv::BvOptimizeSatProof::
+ BITVECTOR_OPTIMIZE_SAT_PROOF_FORMULA)
+ {
+ Debug("bv::clausal") << "Optimizing DRAT" << std::endl;
+ char formulaFilename[] = "/tmp/cvc4-dimacs-XXXXXX";
+ char dratFilename[] = "/tmp/cvc4-drat-XXXXXX";
+ char optDratFilename[] = "/tmp/cvc4-optimized-drat-XXXXXX";
+ char optFormulaFilename[] = "/tmp/cvc4-optimized-formula-XXXXXX";
+ int r;
+ r = mkstemp(formulaFilename);
+ AlwaysAssert(r > 0);
+ close(r);
+ r = mkstemp(dratFilename);
+ AlwaysAssert(r > 0);
+ close(r);
+ r = mkstemp(optDratFilename);
+ AlwaysAssert(r > 0);
+ close(r);
+ r = mkstemp(optFormulaFilename);
+ AlwaysAssert(r > 0);
+ close(r);
+
+ std::ofstream formStream(formulaFilename);
+ printDimacs(formStream, d_clauses, d_originalClauseIndices);
+ formStream.close();
+
+ std::ofstream dratStream(dratFilename);
+ dratStream << d_binaryDratProof.str();
+ dratStream.close();
+
+#if CVC4_USE_DRAT2ER
+ int dratTrimExitCode =
+ drat2er::drat_trim::OptimizeWithDratTrim(formulaFilename,
+ dratFilename,
+ optFormulaFilename,
+ optDratFilename,
+ drat2er::options::QUIET);
+ AlwaysAssert(
+ dratTrimExitCode == 0, "drat-trim exited with %d", dratTrimExitCode);
+#else
+ Unimplemented(
+ "Proof production when using CryptoMiniSat requires drat2er.\n"
+ "Run contrib/get-drat2er, reconfigure with --drat2er, and rebuild");
+#endif
+
+ d_binaryDratProof.str("");
+ Assert(d_binaryDratProof.str().size() == 0);
+
+ std::ifstream lratStream(optDratFilename);
+ std::copy(std::istreambuf_iterator<char>(lratStream),
+ std::istreambuf_iterator<char>(),
+ std::ostreambuf_iterator<char>(d_binaryDratProof));
+
+ if (options::bvOptimizeSatProof()
+ == theory::bv::BvOptimizeSatProof::BITVECTOR_OPTIMIZE_SAT_PROOF_FORMULA)
+ {
+ std::ifstream optFormulaStream{optFormulaFilename};
+ std::vector<prop::SatClause> core = parseDimacs(optFormulaStream);
+ optFormulaStream.close();
+
+ // Now we need to compute the clause indices for the UNSAT core. This is a
+ // bit difficult because drat-trim may have reordered clauses, and/or
+ // removed duplicate literals. We use literal sets as the canonical clause
+ // form.
+ std::unordered_map<
+ std::unordered_set<prop::SatLiteral, prop::SatLiteralHashFunction>,
+ ClauseId,
+ prop::SatClauseSetHashFunction>
+ cannonicalClausesToIndices;
+ for (const auto& kv : d_clauses)
+ {
+ cannonicalClausesToIndices.emplace(
+ std::unordered_set<prop::SatLiteral, prop::SatLiteralHashFunction>{
+ kv.second.begin(), kv.second.end()},
+ kv.first);
+ }
+
+ d_coreClauseIndices.clear();
+ std::unordered_set<prop::SatLiteral, prop::SatLiteralHashFunction>
+ coreClauseCanonical;
+ for (const prop::SatClause& coreClause : core)
+ {
+ coreClauseCanonical.insert(coreClause.begin(), coreClause.end());
+ d_coreClauseIndices.push_back(
+ cannonicalClausesToIndices.at(coreClauseCanonical));
+ coreClauseCanonical.clear();
+ }
+ Debug("bv::clausal") << "Optimizing the DRAT proof and the formula"
+ << std::endl;
+ }
+ else
+ {
+ Debug("bv::clausal") << "Optimizing the DRAT proof but not the formula"
+ << std::endl;
+ d_coreClauseIndices = d_originalClauseIndices;
+ }
+
+ Assert(d_coreClauseIndices.size() > 0);
+ remove(formulaFilename);
+ remove(dratFilename);
+ remove(optDratFilename);
+ remove(optFormulaFilename);
+ Debug("bv::clausal") << "Optimized DRAT" << std::endl;
+ }
+ else
+ {
+ Debug("bv::clausal") << "Not optimizing the formula or the DRAT proof"
+ << std::endl;
+ d_coreClauseIndices = d_originalClauseIndices;
}
}
@@ -120,10 +249,9 @@ void LfscClausalBitVectorProof::printBBDeclarationAndCnf(std::ostream& os,
d_cnfProof->printAtomMapping(d_atomsInBitblastingProof, os, paren, letMap);
os << "\n;; BB-CNF proofs\n";
- for (const auto& idAndClause : d_usedClauses)
+ for (const ClauseId id : d_coreClauseIndices)
{
- d_cnfProof->printCnfProofForClause(
- idAndClause.first, &idAndClause.second, os, paren);
+ d_cnfProof->printCnfProofForClause(id, &d_clauses.at(id), os, paren);
}
}
@@ -137,13 +265,8 @@ void LfscDratBitVectorProof::printEmptyClauseProof(std::ostream& os,
os << "\n;; Proof of input to SAT solver\n";
os << "(@ proofOfSatInput ";
paren << ")";
- std::vector<ClauseId> usedIds;
- usedIds.reserve(d_usedClauses.size());
- for (const auto& idAnd : d_usedClauses)
- {
- usedIds.push_back(idAnd.first);
- };
- LFSCProofPrinter::printSatInputProof(usedIds, os, "bb");
+
+ LFSCProofPrinter::printSatInputProof(d_coreClauseIndices, os, "bb");
os << "\n;; DRAT Proof Value\n";
os << "(@ dratProof ";
@@ -166,19 +289,13 @@ void LfscLratBitVectorProof::printEmptyClauseProof(std::ostream& os,
os << "\n;; Proof of input to SAT solver\n";
os << "(@ proofOfCMap ";
paren << ")";
- std::vector<ClauseId> usedIds;
- usedIds.reserve(d_usedClauses.size());
- for (const auto& idAnd : d_usedClauses)
- {
- usedIds.push_back(idAnd.first);
- };
- LFSCProofPrinter::printCMapProof(usedIds, os, "bb");
+ LFSCProofPrinter::printCMapProof(d_coreClauseIndices, os, "bb");
os << "\n;; DRAT Proof Value\n";
os << "(@ lratProof ";
paren << ")";
- lrat::LratProof pf =
- lrat::LratProof::fromDratProof(d_usedClauses, d_binaryDratProof.str());
+ lrat::LratProof pf = lrat::LratProof::fromDratProof(
+ d_clauses, d_coreClauseIndices, d_binaryDratProof.str());
pf.outputAsLfsc(os);
os << "\n";
@@ -194,8 +311,8 @@ void LfscErBitVectorProof::printEmptyClauseProof(std::ostream& os,
"the BV theory should only be proving bottom directly in the eager "
"bitblasting mode");
- er::ErProof pf =
- er::ErProof::fromBinaryDratProof(d_usedClauses, d_binaryDratProof.str());
+ er::ErProof pf = er::ErProof::fromBinaryDratProof(
+ d_clauses, d_coreClauseIndices, d_binaryDratProof.str());
pf.outputAsLfsc(os);
}
diff --git a/src/proof/clausal_bitvector_proof.h b/src/proof/clausal_bitvector_proof.h
index b10b1ad1c..a410b5b38 100644
--- a/src/proof/clausal_bitvector_proof.h
+++ b/src/proof/clausal_bitvector_proof.h
@@ -61,9 +61,16 @@ class ClausalBitVectorProof : public BitVectorProof
protected:
// A list of all clauses and their ids which are passed into the SAT solver
- std::vector<std::pair<ClauseId, prop::SatClause>> d_usedClauses;
+ std::unordered_map<ClauseId, prop::SatClause> d_clauses{};
+ std::vector<ClauseId> d_originalClauseIndices{};
// Stores the proof recieved from the SAT solver.
- std::ostringstream d_binaryDratProof;
+ std::ostringstream d_binaryDratProof{};
+ std::vector<ClauseId> d_coreClauseIndices{};
+
+ private:
+ // Optimizes the DRAT proof stored in `d_binaryDratProof` and returns a list
+ // of clause actually needed to check that proof (a smaller UNSAT core)
+ void optimizeDratProof();
};
/**
diff --git a/src/proof/dimacs_printer.cpp b/src/proof/dimacs.cpp
index 04f880e11..cced98660 100644
--- a/src/proof/dimacs_printer.cpp
+++ b/src/proof/dimacs.cpp
@@ -1,5 +1,5 @@
/********************* */
-/*! \file dimacs_printer.cpp
+/*! \file dimacs.cpp
** \verbatim
** Top contributors (to current version):
** Alex Ozdemir
@@ -14,7 +14,9 @@
** Defines serialization for SAT problems as DIMACS
**/
-#include "proof/dimacs_printer.h"
+#include "proof/dimacs.h"
+
+#include "base/cvc4_assert.h"
#include <iostream>
@@ -43,14 +45,15 @@ std::ostream& textOut(std::ostream& o, const prop::SatClause& c)
return o << "0";
}
-void printDimacs(
- std::ostream& o,
- const std::vector<std::pair<ClauseId, prop::SatClause>>& usedClauses)
+void printDimacs(std::ostream& o,
+ const std::unordered_map<ClauseId, prop::SatClause>& clauses,
+ const std::vector<ClauseId>& usedIndices)
{
size_t maxVar = 0;
- for (const auto& c : usedClauses)
+ for (const ClauseId i : usedIndices)
{
- for (const auto& l : c.second)
+ const prop::SatClause& c = clauses.at(i);
+ for (const auto& l : c)
{
if (l.getSatVariable() + 1 > maxVar)
{
@@ -58,10 +61,11 @@ void printDimacs(
}
}
}
- o << "p cnf " << maxVar << " " << usedClauses.size() << '\n';
- for (const auto& idAndClause : usedClauses)
+ o << "p cnf " << maxVar << " " << usedIndices.size() << '\n';
+ for (const ClauseId i : usedIndices)
{
- for (const auto& l : idAndClause.second)
+ const prop::SatClause& c = clauses.at(i);
+ for (const auto& l : c)
{
if (l.isNegated())
{
@@ -73,5 +77,44 @@ void printDimacs(
}
}
+std::vector<prop::SatClause> parseDimacs(std::istream& in)
+{
+ std::string tag;
+ uint64_t nVars;
+ uint64_t nClauses;
+
+ in >> tag;
+ Assert(in.good());
+ Assert(tag == "p");
+
+ in >> tag;
+ Assert(in.good());
+ Assert(tag == "cnf");
+
+ in >> nVars;
+ Assert(nVars >= 0);
+
+ in >> nClauses;
+ Assert(nClauses >= 0);
+
+ std::vector<prop::SatClause> cnf;
+ for (uint64_t i = 0; i < nClauses; ++i)
+ {
+ cnf.emplace_back();
+ int64_t lit;
+ in >> lit;
+ Assert(in.good());
+ while (lit != 0)
+ {
+ cnf.back().emplace_back(std::abs(lit) - 1, lit < 0);
+ in >> lit;
+ Assert(static_cast<uint64_t>(std::abs(lit)) <= nVars);
+ Assert(in.good());
+ }
+ }
+
+ return cnf;
+}
+
} // namespace proof
} // namespace CVC4
diff --git a/src/proof/dimacs_printer.h b/src/proof/dimacs.h
index 2ae4abefa..5956c5d26 100644
--- a/src/proof/dimacs_printer.h
+++ b/src/proof/dimacs.h
@@ -1,5 +1,5 @@
/********************* */
-/*! \file dimacs_printer.h
+/*! \file dimacs.h
** \verbatim
** Top contributors (to current version):
** Alex Ozdemir
@@ -11,16 +11,17 @@
**
** \brief DIMACS SAT Problem Format
**
- ** Defines serialization for SAT problems as DIMACS
+ ** Defines serialization/deserialization for SAT problems as DIMACS
**/
#include "cvc4_private.h"
-#ifndef CVC4__PROOF__DIMACS_PRINTER_H
-#define CVC4__PROOF__DIMACS_PRINTER_H
+#ifndef CVC4__PROOF__DIMACS_H
+#define CVC4__PROOF__DIMACS_H
#include <iosfwd>
#include <memory>
+#include <unordered_map>
#include "proof/clause_id.h"
#include "prop/sat_solver_types.h"
@@ -56,11 +57,13 @@ std::ostream& textOut(std::ostream& o, const prop::SatClause& c);
* @param o where to print to
* @param usedClauses the CNF formula
*/
-void printDimacs(
- std::ostream& o,
- const std::vector<std::pair<ClauseId, prop::SatClause>>& usedClauses);
+void printDimacs(std::ostream& o,
+ const std::unordered_map<ClauseId, prop::SatClause>& clauses,
+ const std::vector<ClauseId>& usedIndices);
+
+std::vector<prop::SatClause> parseDimacs(std::istream& i);
} // namespace proof
} // namespace CVC4
-#endif // CVC4__PROOF__DIMACS_PRINTER_H
+#endif // CVC4__PROOF__DIMACS_H
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]);
- }
}
}
diff --git a/src/proof/er/er_proof.h b/src/proof/er/er_proof.h
index f5af0783b..d6cbd9213 100644
--- a/src/proof/er/er_proof.h
+++ b/src/proof/er/er_proof.h
@@ -27,6 +27,7 @@
#define CVC4__PROOF__ER__ER_PROOF_H
#include <memory>
+#include <unordered_map>
#include <vector>
#include "proof/clause_id.h"
@@ -36,8 +37,6 @@ namespace CVC4 {
namespace proof {
namespace er {
-using ClauseUseRecord = std::vector<std::pair<ClauseId, prop::SatClause>>;
-
/**
* A definition of the form:
* newVar <-> p v (~x_1 ^ ~x_2 ^ ... ^ ~x_n)
@@ -116,11 +115,14 @@ class ErProof
/**
* Construct an ER proof from a DRAT proof, using drat2er
*
- * @param usedClauses The CNF formula that we're deriving bottom from.
- * @param dratBinary The DRAT proof from the SAT solver, as a binary stream.
+ * @param clauses A store of clauses that might be in our formula
+ * @param usedIds the ids of clauses that are actually in our formula
+ * @param dratBinary The DRAT proof from the SAT solver, as a binary stream
*/
- static ErProof fromBinaryDratProof(const ClauseUseRecord& usedClauses,
- const std::string& dratBinary);
+ static ErProof fromBinaryDratProof(
+ const std::unordered_map<ClauseId, prop::SatClause>& clauses,
+ const std::vector<ClauseId>& usedIds,
+ const std::string& dratBinary);
/**
* Construct an ER proof from a TRACECHECK ER proof
@@ -128,10 +130,13 @@ class ErProof
* This basically just identifies groups of lines which correspond to
* definitions, and extracts them.
*
- * @param usedClauses The CNF formula that we're deriving bottom from.
+ * @param clauses A store of clauses that might be in our formula
+ * @param usedIds the ids of clauses that are actually in our formula
* @param tracecheck The TRACECHECK proof, as a stream.
*/
- ErProof(const ClauseUseRecord& usedClauses, TraceCheckProof&& tracecheck);
+ ErProof(const std::unordered_map<ClauseId, prop::SatClause>& clauses,
+ const std::vector<ClauseId>& usedIds,
+ TraceCheckProof&& tracecheck);
/**
* Write the ER proof as an LFSC value of type (holds cln).
diff --git a/src/proof/lrat/lrat_proof.cpp b/src/proof/lrat/lrat_proof.cpp
index a1939ec92..e414c64c9 100644
--- a/src/proof/lrat/lrat_proof.cpp
+++ b/src/proof/lrat/lrat_proof.cpp
@@ -26,7 +26,7 @@
#include "base/cvc4_assert.h"
#include "base/output.h"
-#include "proof/dimacs_printer.h"
+#include "proof/dimacs.h"
#include "proof/lfsc_proof_printer.h"
#if CVC4_USE_DRAT2ER
@@ -104,6 +104,7 @@ void printHints(std::ostream& o,
*/
void printIndices(std::ostream& o, const std::vector<ClauseIdx>& indices)
{
+ Assert(indices.size() > 0);
// Verify that the indices are sorted!
for (size_t i = 0, n = indices.size() - 1; i < n; ++i)
{
@@ -123,7 +124,8 @@ void printIndices(std::ostream& o, const std::vector<ClauseIdx>& indices)
// Prints the LRAT addition line in textual format
LratProof LratProof::fromDratProof(
- const std::vector<std::pair<ClauseId, prop::SatClause>>& usedClauses,
+ const std::unordered_map<ClauseId, prop::SatClause>& clauses,
+ const std::vector<ClauseId> usedIds,
const std::string& dratBinary)
{
std::ostringstream cmd;
@@ -141,7 +143,7 @@ LratProof LratProof::fromDratProof(
AlwaysAssert(r > 0);
close(r);
std::ofstream formStream(formulaFilename);
- printDimacs(formStream, usedClauses);
+ printDimacs(formStream, clauses, usedIds);
formStream.close();
std::ofstream dratStream(dratFilename);
@@ -206,10 +208,13 @@ LratProof::LratProof(std::istream& textualProof)
}
clauses.push_back(di);
}
- std::sort(clauses.begin(), clauses.end());
- std::unique_ptr<LratInstruction> instr(
- new LratDeletion(clauseIdx, std::move(clauses)));
- d_instructions.push_back(std::move(instr));
+ if (clauses.size() > 0)
+ {
+ std::sort(clauses.begin(), clauses.end());
+ std::unique_ptr<LratInstruction> instr(
+ new LratDeletion(clauseIdx, std::move(clauses)));
+ d_instructions.push_back(std::move(instr));
+ }
}
else
{
diff --git a/src/proof/lrat/lrat_proof.h b/src/proof/lrat/lrat_proof.h
index 33b2fad3f..54db1837d 100644
--- a/src/proof/lrat/lrat_proof.h
+++ b/src/proof/lrat/lrat_proof.h
@@ -129,15 +129,13 @@ class LratProof
/**
* @brief Construct an LRAT proof from a DRAT proof, using drat-trim
*
- * @param usedClauses The CNF formula that we're deriving bottom from.
- * It's a map because other parts of the system represent
- * it this way.
- * @param clauseOrder A record of the order in which those clauses were
- * given to the SAT solver.
+ * @param clauses A store of clauses that might be in our formula
+ * @param usedIds the ids of clauses that are actually in our formula
* @param dratBinary The DRAT proof from the SAT solver, as a binary stream.
*/
static LratProof fromDratProof(
- const std::vector<std::pair<ClauseId, prop::SatClause>>& usedClauses,
+ const std::unordered_map<ClauseId, prop::SatClause>& clauses,
+ const std::vector<ClauseId> usedIds,
const std::string& dratBinary);
/**
* @brief Construct an LRAT proof from its textual representation
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index 66198946f..303295112 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -31,6 +31,7 @@
#include "base/configuration.h"
#include "base/configuration_private.h"
+#include "base/cvc4_check.h"
#include "base/exception.h"
#include "base/listener.h"
#include "base/modal_exception.h"
@@ -888,6 +889,7 @@ SmtEngine::SmtEngine(ExprManager* em)
d_earlyTheoryPP(true),
d_globalNegation(false),
d_status(),
+ d_expectedStatus(),
d_replayStream(NULL),
d_private(NULL),
d_statisticsRegistry(NULL),
@@ -2420,7 +2422,7 @@ void SmtEngine::setInfo(const std::string& key, const CVC4::SExpr& value)
throw OptionException("argument to (set-info :status ..) must be "
"`sat' or `unsat' or `unknown'");
}
- d_status = Result(s, d_filename);
+ d_expectedStatus = Result(s, d_filename);
return;
}
throw UnrecognizedOptionException();
@@ -3747,6 +3749,13 @@ Result SmtEngine::checkSatisfiability(const vector<Expr>& assumptions,
// Remember the status
d_status = r;
+ if (!d_expectedStatus.isUnknown() && !d_status.isUnknown()
+ && d_status != d_expectedStatus)
+ {
+ CVC4_FATAL() << "Expected result " << d_expectedStatus << " but got "
+ << d_status;
+ }
+ d_expectedStatus = Result();
setProblemExtended(false);
@@ -4428,13 +4437,7 @@ void SmtEngine::checkProof()
std::string logicString = d_logic.getLogicString();
- if (!(
- // Pure logics
- logicString == "QF_UF" || logicString == "QF_AX"
- || logicString == "QF_BV" ||
- // Non-pure logics
- logicString == "QF_AUF" || logicString == "QF_UFBV"
- || logicString == "QF_ABV" || logicString == "QF_AUFBV"))
+ if (!(d_logic <= LogicInfo("QF_AUFBVLRA")))
{
// This logic is not yet supported
Notice() << "Notice: no proof-checking for " << logicString << " proofs yet"
diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h
index 165e93997..5913716e6 100644
--- a/src/smt/smt_engine.h
+++ b/src/smt/smt_engine.h
@@ -263,6 +263,11 @@ class CVC4_PUBLIC SmtEngine {
Result d_status;
/**
+ * The expected status of the next satisfiability check.
+ */
+ Result d_expectedStatus;
+
+ /**
* The input file name (if any) or the name set through setInfo (if any)
*/
std::string d_filename;
diff --git a/src/smt/smt_engine.i b/src/smt/smt_engine.i
index c054cb666..4018cc3dc 100644
--- a/src/smt/smt_engine.i
+++ b/src/smt/smt_engine.i
@@ -42,6 +42,9 @@ SWIGEXPORT void JNICALL Java_edu_nyu_acsys_CVC4_SmtEngine_dlRef(JNIEnv* jenv, jc
swigCPtr = 0;
}
}
+
+%template(Map_ExprExpr) std::map<CVC4::Expr, CVC4::Expr>;
+
#endif // SWIGJAVA
%ignore CVC4::SmtEngine::setLogic(const char*);
diff --git a/src/theory/fp/fp_converter.cpp b/src/theory/fp/fp_converter.cpp
index a69cf8c96..fbdce8cd5 100644
--- a/src/theory/fp/fp_converter.cpp
+++ b/src/theory/fp/fp_converter.cpp
@@ -157,17 +157,17 @@ symbolicRoundingMode traits::RTN(void) { return symbolicRoundingMode(0x08); };
symbolicRoundingMode traits::RTZ(void) { return symbolicRoundingMode(0x10); };
void traits::precondition(const bool b)
{
- Assert(b);
+ AlwaysAssert(b);
return;
}
void traits::postcondition(const bool b)
{
- Assert(b);
+ AlwaysAssert(b);
return;
}
void traits::invariant(const bool b)
{
- Assert(b);
+ AlwaysAssert(b);
return;
}
diff --git a/src/theory/logic_info.cpp b/src/theory/logic_info.cpp
index 1712bb30a..e21d1f630 100644
--- a/src/theory/logic_info.cpp
+++ b/src/theory/logic_info.cpp
@@ -17,9 +17,10 @@
**/
#include "theory/logic_info.h"
-#include <string>
#include <cstring>
+#include <iostream>
#include <sstream>
+#include <string>
#include "base/cvc4_assert.h"
#include "expr/kind.h"
@@ -207,13 +208,15 @@ bool LogicInfo::operator==(const LogicInfo& other) const {
PrettyCheckArgument(d_sharingTheories == other.d_sharingTheories, *this,
"LogicInfo internal inconsistency");
+ bool res = d_cardinalityConstraints == other.d_cardinalityConstraints
+ && d_higherOrder == other.d_higherOrder;
if(isTheoryEnabled(theory::THEORY_ARITH)) {
return d_integers == other.d_integers && d_reals == other.d_reals
&& d_transcendentals == other.d_transcendentals
&& d_linear == other.d_linear
- && d_differenceLogic == other.d_differenceLogic;
+ && d_differenceLogic == other.d_differenceLogic && res;
} else {
- return true;
+ return res;
}
}
@@ -227,13 +230,15 @@ bool LogicInfo::operator<=(const LogicInfo& other) const {
}
PrettyCheckArgument(d_sharingTheories <= other.d_sharingTheories, *this,
"LogicInfo internal inconsistency");
+ bool res = (!d_cardinalityConstraints || other.d_cardinalityConstraints)
+ && (!d_higherOrder || other.d_higherOrder);
if(isTheoryEnabled(theory::THEORY_ARITH) && other.isTheoryEnabled(theory::THEORY_ARITH)) {
return (!d_integers || other.d_integers) && (!d_reals || other.d_reals)
&& (!d_transcendentals || other.d_transcendentals)
&& (d_linear || !other.d_linear)
- && (d_differenceLogic || !other.d_differenceLogic);
+ && (d_differenceLogic || !other.d_differenceLogic) && res;
} else {
- return true;
+ return res;
}
}
@@ -247,13 +252,15 @@ bool LogicInfo::operator>=(const LogicInfo& other) const {
}
PrettyCheckArgument(d_sharingTheories >= other.d_sharingTheories, *this,
"LogicInfo internal inconsistency");
+ bool res = (d_cardinalityConstraints || !other.d_cardinalityConstraints)
+ && (d_higherOrder || !other.d_higherOrder);
if(isTheoryEnabled(theory::THEORY_ARITH) && other.isTheoryEnabled(theory::THEORY_ARITH)) {
return (d_integers || !other.d_integers) && (d_reals || !other.d_reals)
&& (d_transcendentals || !other.d_transcendentals)
&& (!d_linear || other.d_linear)
- && (!d_differenceLogic || other.d_differenceLogic);
+ && (!d_differenceLogic || other.d_differenceLogic) && res;
} else {
- return true;
+ return res;
}
}
diff --git a/src/util/floatingpoint.cpp b/src/util/floatingpoint.cpp
index 4aed27c30..f7e73ca4b 100644
--- a/src/util/floatingpoint.cpp
+++ b/src/util/floatingpoint.cpp
@@ -441,17 +441,17 @@ rm traits::RTZ(void) { return ::CVC4::roundTowardZero; };
void traits::precondition(const prop &p)
{
- Assert(p);
+ AlwaysAssert(p);
return;
}
void traits::postcondition(const prop &p)
{
- Assert(p);
+ AlwaysAssert(p);
return;
}
void traits::invariant(const prop &p)
{
- Assert(p);
+ AlwaysAssert(p);
return;
}
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback