void BitVectorProof::initSatProof(CVC4::BVMinisat::Solver* solver) {
Assert (d_resolutionProof == NULL);
- d_resolutionProof = new LFSCBVSatProof(solver, "bb", true);
+ d_resolutionProof = new LFSCBVSatProof(solver, &d_fakeContext, "bb", true);
}
void BitVectorProof::initCnfProof(prop::CnfStream* cnfStream,
std::map<Expr,std::string> d_constantLetMap;
bool d_useConstantLetification;
+ context::Context d_fakeContext;
public:
BitVectorProof(theory::bv::TheoryBV* bv, TheoryProofEngine* proofEngine);
return os.str();
}
-ProofManager::ProofManager(ProofFormat format):
+ProofManager::ProofManager(context::Context* context, ProofFormat format):
+ d_context(context),
d_satProof(NULL),
d_cnfProof(NULL),
d_theoryProof(NULL),
d_inputFormulas(),
- d_inputCoreFormulas(),
- d_outputCoreFormulas(),
+ d_inputCoreFormulas(context),
+ d_outputCoreFormulas(context),
d_nextId(0),
d_fullProof(NULL),
d_format(format),
- d_deps()
+ d_deps(context)
{
}
void ProofManager::initSatProof(Minisat::Solver* solver) {
Assert (currentPM()->d_satProof == NULL);
Assert(currentPM()->d_format == LFSC);
- currentPM()->d_satProof = new LFSCCoreSatProof(solver, "");
+ currentPM()->d_satProof = new LFSCCoreSatProof(solver, d_context, "");
}
void ProofManager::initCnfProof(prop::CnfStream* cnfStream,
}
}
+void ProofManager::traceDeps(TNode n, CDExprSet* 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`%s'", n.toString().c_str());
+ }
+ 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::traceUnsatCore() {
Assert (options::unsatCores());
- constructSatProof();
+ d_satProof->refreshProof();
IdToSatClause used_lemmas;
IdToSatClause used_inputs;
d_satProof->collectClausesUsed(used_inputs,
used_lemmas);
+
IdToSatClause::const_iterator it = used_inputs.begin();
for(; it != used_inputs.end(); ++it) {
Node node = d_cnfProof->getAssertionForClause(it->first);
return d_satProof->derivedEmptyClause();
}
+std::vector<Expr> ProofManager::extractUnsatCore() {
+ std::vector<Expr> result;
+ output_core_iterator it = begin_unsat_core();
+ output_core_iterator end = end_unsat_core();
+ while ( it != end ) {
+ result.push_back(*it);
+ ++it;
+ }
+ return result;
+}
+
void ProofManager::constructSatProof() {
if (!d_satProof->proofConstructed()) {
d_satProof->constructProof();
if( !dep.isNull() && d_deps.find(dep) == d_deps.end()) {
Debug("cores") << "WHERE DID " << dep << " come from ??" << std::endl;
}
- //Assert(d_deps.find(dep) != d_deps.end());
- d_deps[n].push_back(dep);
+ std::vector<Node> deps = d_deps[n].get();
+ deps.push_back(dep);
+ d_deps[n].set(deps);
}
}
#include <iosfwd>
#include <map>
#include "expr/node.h"
+#include "context/cdhashset.h"
+#include "context/cdhashmap.h"
#include "proof/clause_id.h"
#include "proof/proof.h"
#include "proof/proof_utils.h"
std::string append(const std::string& str, uint64_t num);
typedef __gnu_cxx::hash_map < ClauseId, prop::SatClause* > IdToSatClause;
-typedef __gnu_cxx::hash_set<Expr, ExprHashFunction > ExprSet;
+typedef __gnu_cxx::hash_set<Expr, ExprHashFunction> ExprSet;
+typedef context::CDHashSet<Expr, ExprHashFunction> CDExprSet;
typedef __gnu_cxx::hash_set<Node, NodeHashFunction > NodeSet;
typedef __gnu_cxx::hash_map<Node, std::vector<Node>, NodeHashFunction > NodeToNodes;
+typedef context::CDHashMap<Node, std::vector<Node>, NodeHashFunction > CDNodeToNodes;
typedef std::hash_set<ClauseId> IdHashSet;
enum ProofRule {
};
class ProofManager {
+ context::Context* d_context;
+
CoreSatProof* d_satProof;
CnfProof* d_cnfProof;
TheoryProofEngine* d_theoryProof;
// information that will need to be shared across proofs
ExprSet d_inputFormulas;
std::map<Expr, std::string> d_inputFormulaToName;
- ExprSet d_inputCoreFormulas;
- ExprSet d_outputCoreFormulas;
+ CDExprSet d_inputCoreFormulas;
+ CDExprSet d_outputCoreFormulas;
SkolemizationManager d_skolemizationManager;
Proof* d_fullProof;
ProofFormat d_format; // used for now only in debug builds
- NodeToNodes d_deps;
+ CDNodeToNodes d_deps;
std::set<Type> d_printedTypes;
LogicInfo d_logic;
public:
- ProofManager(ProofFormat format = LFSC);
+ ProofManager(context::Context* context, ProofFormat format = LFSC);
~ProofManager();
static ProofManager* currentPM();
// initialization
- static void initSatProof(Minisat::Solver* solver);
+ void initSatProof(Minisat::Solver* solver);
static void initCnfProof(CVC4::prop::CnfStream* cnfStream,
context::Context* ctx);
static void initTheoryProofEngine();
// trace dependences back to unsat core
void traceDeps(TNode n, ExprSet* coreAssertions);
+ void traceDeps(TNode n, CDExprSet* coreAssertions);
void traceUnsatCore();
- assertions_iterator begin_unsat_core() const { return d_outputCoreFormulas.begin(); }
- assertions_iterator end_unsat_core() const { return d_outputCoreFormulas.end(); }
+
+ typedef CDExprSet::const_iterator output_core_iterator;
+
+ output_core_iterator begin_unsat_core() const { return d_outputCoreFormulas.begin(); }
+ output_core_iterator end_unsat_core() const { return d_outputCoreFormulas.end(); }
size_t size_unsat_core() const { return d_outputCoreFormulas.size(); }
+ std::vector<Expr> extractUnsatCore();
bool unsatCoreAvailable() const;
void getLemmasInUnsatCore(theory::TheoryId theory, std::vector<Node> &lemmas);
#include <sstream>
#include <vector>
+#include "context/cdhashmap.h"
#include "expr/expr.h"
#include "proof/clause_id.h"
#include "proof/proof_manager.h"
typedef std::set<typename Solver::TVar> VarSet;
typedef std::hash_map<ClauseId, typename Solver::TCRef> IdCRefMap;
typedef std::hash_map<typename Solver::TCRef, ClauseId> ClauseIdMap;
- typedef std::hash_map<ClauseId, typename Solver::TLit> IdUnitMap;
- typedef std::hash_map<int, ClauseId> UnitIdMap;
- typedef std::hash_map<ClauseId, ResolutionChain*> IdResMap;
+ typedef context::CDHashMap<ClauseId, typename Solver::TLit> IdUnitMap;
+ typedef context::CDHashMap<int, ClauseId> UnitIdMap;
+ typedef context::CDHashMap<ClauseId, ResolutionChain*> IdResMap;
typedef std::hash_map<ClauseId, uint64_t> IdProofRuleMap;
typedef std::vector<ResolutionChain*> ResStack;
typedef std::set<ClauseId> IdSet;
typedef __gnu_cxx::hash_map<ClauseId, LitVector*> IdToConflicts;
public:
- TSatProof(Solver* solver, const std::string& name, bool checkRes = false);
+ TSatProof(Solver* solver, context::Context* context,
+ const std::string& name, bool checkRes = false);
virtual ~TSatProof();
void setCnfProof(CnfProof* cnf_proof);
*/
void constructProof(ClauseId id);
void constructProof() { constructProof(d_emptyClauseId); }
+ void refreshProof(ClauseId id);
+ void refreshProof() { refreshProof(d_emptyClauseId); }
bool proofConstructed() const;
void collectClauses(ClauseId id);
bool derivedEmptyClause() const;
// Internal data.
typename Solver::Solver* d_solver;
+ context::Context* d_context;
CnfProof* d_cnfProof;
// clauses
class LFSCSatProof : public TSatProof<SatSolver> {
private:
public:
- LFSCSatProof(SatSolver* solver, const std::string& name,
- bool checkRes = false)
- : TSatProof<SatSolver>(solver, name, checkRes) {}
+ LFSCSatProof(SatSolver* solver, context::Context* context,
+ const std::string& name, bool checkRes = false)
+ : TSatProof<SatSolver>(solver, context, name, checkRes) {}
virtual void printResolution(ClauseId id, std::ostream& out,
std::ostream& paren);
virtual void printResolutions(std::ostream& out, std::ostream& paren);
/// SatProof
template <class Solver>
-TSatProof<Solver>::TSatProof(Solver* solver, const std::string& name,
- bool checkRes)
+TSatProof<Solver>::TSatProof(Solver* solver, context::Context* context,
+ const std::string& name, bool checkRes)
: d_solver(solver),
+ d_context(context),
d_cnfProof(NULL),
d_idClause(),
d_clauseId(),
- d_idUnit(),
+ d_idUnit(context),
+ d_unitId(context),
d_deleted(),
d_inputClauses(),
d_lemmaClauses(),
d_assumptions(),
d_assumptionConflicts(),
d_assumptionConflictsDebug(),
- d_resolutionChains(),
+ d_resolutionChains(d_context),
d_resStack(),
d_checkRes(checkRes),
d_emptyClauseId(ClauseIdEmpty),
ResolutionChainIterator resolution_it = d_resolutionChains.begin();
ResolutionChainIterator resolution_it_end = d_resolutionChains.end();
for (; resolution_it != resolution_it_end; ++resolution_it) {
- ResChain<Solver>* current = resolution_it->second;
+ ResChain<Solver>* current = (*resolution_it).second;
delete current;
}
ClauseId TSatProof<Solver>::getClauseIdForLiteral(
typename Solver::TLit lit) const {
Assert(hasClauseIdForLiteral(lit));
- return d_unitId.find(toInt(lit))->second;
+ return (*d_unitId.find(toInt(lit))).second;
}
template <class Solver>
template <class Solver>
typename Solver::TLit TSatProof<Solver>::getUnit(ClauseId id) const {
Assert(isUnit(id));
- return d_idUnit.find(id)->second;
+ return (*d_idUnit.find(id)).second;
}
template <class Solver>
template <class Solver>
ClauseId TSatProof<Solver>::getUnitId(typename Solver::TLit lit) const {
Assert(isUnit(lit));
- return d_unitId.find(toInt(lit))->second;
+ return (*d_unitId.find(toInt(lit))).second;
}
template <class Solver>
const typename TSatProof<Solver>::ResolutionChain&
TSatProof<Solver>::getResolutionChain(ClauseId id) const {
Assert(hasResolutionChain(id));
- const ResolutionChain* chain = d_resolutionChains.find(id)->second;
+ const ResolutionChain* chain = (*d_resolutionChains.find(id)).second;
return *chain;
}
typename ClauseIdMap::iterator it = d_clauseId.find(clause);
if (it == d_clauseId.end()) {
ClauseId newId = ProofManager::currentPM()->nextId();
+
d_clauseId.insert(std::make_pair(clause, newId));
d_idClause.insert(std::make_pair(newId, clause));
if (kind == INPUT) {
typename UnitIdMap::iterator it = d_unitId.find(toInt(lit));
if (it == d_unitId.end()) {
ClauseId newId = ProofManager::currentPM()->nextId();
- d_unitId.insert(std::make_pair(toInt(lit), newId));
- d_idUnit.insert(std::make_pair(newId, lit));
+
+ if (d_unitId.find(toInt(lit)) == d_unitId.end())
+ d_unitId[toInt(lit)] = newId;
+ if (d_idUnit.find(newId) == d_idUnit.end())
+ d_idUnit[newId] = lit;
if (kind == INPUT) {
Assert(d_inputClauses.find(newId) == d_inputClauses.end());
// could be the case that a resolution chain for this clause already
// exists (e.g. when removing units in addClause).
if (hasResolutionChain(id)) {
- ResChain<Solver>* current = d_resolutionChains.find(id)->second;
+ ResChain<Solver>* current = (*d_resolutionChains.find(id)).second;
delete current;
- d_resolutionChains.erase(id);
}
- Assert(!hasResolutionChain(id));
+ if (d_resolutionChains.find(id) == d_resolutionChains.end())
+ d_resolutionChains.insert(id, res);
- d_resolutionChains.insert(std::make_pair(id, res));
if (Debug.isOn("proof:sat")) {
printRes(id);
}
template <class Solver>
ClauseId TSatProof<Solver>::resolveUnit(typename Solver::TLit lit) {
// first check if we already have a resolution for lit
+
if (isUnit(lit)) {
ClauseId id = getClauseIdForLiteral(lit);
Assert(hasResolutionChain(id) || isInputClause(id) || isLemmaClause(id));
typename Solver::TLit lit = d_idUnit[conflict_id];
ClauseId res_id = resolveUnit(~lit);
res->addStep(lit, res_id, !sign(lit));
-
registerResolution(d_emptyClauseId, res);
-
return;
+
} else {
Assert(!d_storedUnitConflict);
conflict_id = registerClause(conflict_ref, LEARNT); // FIXME
if (Debug.isOn("proof:sat")) {
Debug("proof:sat") << "proof::finalizeProof Final Conflict ";
print(conflict_id);
+ Debug("proof:sat") << std::endl;
}
ResChain<Solver>* res = new ResChain<Solver>(conflict_id);
res->addStep(lit, res_id, !sign(lit));
conflict_size = conflict.size();
}
+
registerResolution(d_emptyClauseId, res);
}
collectClauses(conflict);
}
+template <class Solver>
+void TSatProof<Solver>::refreshProof(ClauseId conflict) {
+ IdToSatClause::const_iterator seen_lemma_it = d_seenLemmas.begin();
+ IdToSatClause::const_iterator seen_lemma_end = d_seenLemmas.end();
+
+ for (; seen_lemma_it != seen_lemma_end; ++seen_lemma_it) {
+ if (d_deletedTheoryLemmas.find(seen_lemma_it->first) == d_deletedTheoryLemmas.end())
+ delete seen_lemma_it->second;
+ }
+
+ IdToSatClause::const_iterator seen_input_it = d_seenInputs.begin();
+ IdToSatClause::const_iterator seen_input_end = d_seenInputs.end();
+
+ for (; seen_input_it != seen_input_end; ++seen_input_it) {
+ delete seen_input_it->second;
+ }
+
+ d_seenInputs.clear();
+ d_seenLemmas.clear();
+ d_seenLearnt.clear();
+
+ collectClauses(conflict);
+}
+
template <class Solver>
bool TSatProof<Solver>::proofConstructed() const {
return d_satProofConstructed;
public:
UnsatCore() : d_smt(NULL) {}
- template <class T>
- UnsatCore(SmtEngine* smt, T begin, T end) : d_smt(smt), d_core(begin, end) {
+ UnsatCore(SmtEngine* smt, std::vector<Expr> core) : d_smt(smt), d_core(core) {
initMessage();
}
, propagation_budget (-1)
, asynch_interrupt (false)
{
- PROOF(ProofManager::initSatProof(this);)
+ PROOF(ProofManager::currentPM()->initSatProof(this);)
// Create the constant variables
varTrue = newVar(true, false, false);
// being parsed from the input file. Because of this, we cannot trust
// that options::proof() is set correctly yet.
#ifdef CVC4_PROOF
- d_proofManager = new ProofManager();
+ d_proofManager = new ProofManager(d_userContext);
#endif
// We have mutual dependency here, so we add the prop engine to the theory
}
}
- if(options::incrementalSolving() && (options::proof() || options::unsatCores())) {
+ if(options::incrementalSolving() && options::proof()) {
Warning() << "SmtEngine: turning off incremental solving mode (not yet supported with --proof or --produce-unsat-cores, try --tear-down-incremental instead)" << endl;
setOption("incremental", SExpr("false"));
}
}
d_proofManager->traceUnsatCore();// just to trigger core creation
- return UnsatCore(this, d_proofManager->begin_unsat_core(), d_proofManager->end_unsat_core());
+ return UnsatCore(this, d_proofManager->extractUnsatCore());
#else /* IS_PROOFS_BUILD */
throw ModalException("This build of CVC4 doesn't have proof support (required for unsat cores).");
#endif /* IS_PROOFS_BUILD */