mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
additional robustness check for incremental sat solver core when it recieves interpreted constants, added PB equality to interface and special handling of equalities to adddress performance gap documented in #755
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
fefd00aa49
commit
461e88e34c
21 changed files with 430 additions and 84 deletions
|
@ -196,6 +196,7 @@ public:
|
|||
|
||||
virtual lbool get_consequences(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) {
|
||||
switch_inc_mode();
|
||||
m_use_solver1_results = false;
|
||||
return m_solver2->get_consequences(asms, vars, consequences);
|
||||
}
|
||||
|
||||
|
|
179
src/solver/solver2tactic.cpp
Normal file
179
src/solver/solver2tactic.cpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*++
|
||||
Copyright (c) 2016 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
solver2tactic.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Convert solver to a tactic.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2016-10-17
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
|
||||
#include "solver.h"
|
||||
#include "tactic.h"
|
||||
#include"filter_model_converter.h"
|
||||
#include "solver2tactic.h"
|
||||
#include "ast_util.h"
|
||||
|
||||
typedef obj_map<expr, expr *> expr2expr_map;
|
||||
|
||||
void extract_clauses_and_dependencies(goal_ref const& g, expr_ref_vector& clauses, ptr_vector<expr>& assumptions, expr2expr_map& bool2dep, ref<filter_model_converter>& fmc) {
|
||||
expr2expr_map dep2bool;
|
||||
ptr_vector<expr> deps;
|
||||
ast_manager& m = g->m();
|
||||
expr_ref_vector clause(m);
|
||||
unsigned sz = g->size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * f = g->form(i);
|
||||
expr_dependency * d = g->dep(i);
|
||||
if (d == 0 || !g->unsat_core_enabled()) {
|
||||
clauses.push_back(f);
|
||||
}
|
||||
else {
|
||||
// create clause (not d1 \/ ... \/ not dn \/ f) when the d's are the assumptions/dependencies of f.
|
||||
clause.reset();
|
||||
clause.push_back(f);
|
||||
deps.reset();
|
||||
m.linearize(d, deps);
|
||||
SASSERT(!deps.empty()); // d != 0, then deps must not be empty
|
||||
ptr_vector<expr>::iterator it = deps.begin();
|
||||
ptr_vector<expr>::iterator end = deps.end();
|
||||
for (; it != end; ++it) {
|
||||
expr * d = *it;
|
||||
if (is_uninterp_const(d) && m.is_bool(d)) {
|
||||
// no need to create a fresh boolean variable for d
|
||||
if (!bool2dep.contains(d)) {
|
||||
assumptions.push_back(d);
|
||||
bool2dep.insert(d, d);
|
||||
}
|
||||
clause.push_back(m.mk_not(d));
|
||||
}
|
||||
else {
|
||||
// must normalize assumption
|
||||
expr * b = 0;
|
||||
if (!dep2bool.find(d, b)) {
|
||||
b = m.mk_fresh_const(0, m.mk_bool_sort());
|
||||
dep2bool.insert(d, b);
|
||||
bool2dep.insert(b, d);
|
||||
assumptions.push_back(b);
|
||||
if (!fmc) {
|
||||
fmc = alloc(filter_model_converter, m);
|
||||
}
|
||||
fmc->insert(to_app(b)->get_decl());
|
||||
}
|
||||
clause.push_back(m.mk_not(b));
|
||||
}
|
||||
}
|
||||
SASSERT(clause.size() > 1);
|
||||
expr_ref cls(m);
|
||||
cls = mk_or(m, clause.size(), clause.c_ptr());
|
||||
clauses.push_back(cls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class solver2tactic : public tactic {
|
||||
ast_manager& m;
|
||||
ref<solver> m_solver;
|
||||
params_ref m_params;
|
||||
|
||||
public:
|
||||
solver2tactic(solver* s):
|
||||
m(s->get_manager()),
|
||||
m_solver(s)
|
||||
{}
|
||||
|
||||
virtual void updt_params(params_ref const & p) {
|
||||
m_solver->updt_params(p);
|
||||
}
|
||||
|
||||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
m_solver->collect_param_descrs(r);
|
||||
}
|
||||
|
||||
virtual void operator()(/* in */ goal_ref const & in,
|
||||
/* out */ goal_ref_buffer & result,
|
||||
/* out */ model_converter_ref & mc,
|
||||
/* out */ proof_converter_ref & pc,
|
||||
/* out */ expr_dependency_ref & core) {
|
||||
expr_ref_vector clauses(m);
|
||||
expr2expr_map bool2dep;
|
||||
ptr_vector<expr> assumptions;
|
||||
ref<filter_model_converter> fmc;
|
||||
extract_clauses_and_dependencies(in, clauses, assumptions, bool2dep, fmc);
|
||||
m_solver->push();
|
||||
m_solver->assert_expr(clauses);
|
||||
lbool r = m_solver->check_sat(assumptions.size(), assumptions.c_ptr());
|
||||
switch (r) {
|
||||
case l_true:
|
||||
if (in->models_enabled()) {
|
||||
model_ref mdl;
|
||||
m_solver->get_model(mdl);
|
||||
mc = model2model_converter(mdl.get());
|
||||
mc = concat(fmc.get(), mc.get());
|
||||
}
|
||||
in->reset();
|
||||
result.push_back(in.get());
|
||||
pc = 0;
|
||||
core = 0;
|
||||
break;
|
||||
case l_false: {
|
||||
in->reset();
|
||||
proof* pr = 0;
|
||||
expr_dependency* lcore = 0;
|
||||
if (in->proofs_enabled()) {
|
||||
pr = m_solver->get_proof();
|
||||
}
|
||||
if (in->unsat_core_enabled()) {
|
||||
ptr_vector<expr> core;
|
||||
m_solver->get_unsat_core(core);
|
||||
for (unsigned i = 0; i < core.size(); ++i) {
|
||||
lcore = m.mk_join(lcore, m.mk_leaf(bool2dep.find(core[i])));
|
||||
}
|
||||
}
|
||||
in->assert_expr(m.mk_false(), pr, lcore);
|
||||
result.push_back(in.get());
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
break;
|
||||
}
|
||||
case l_undef:
|
||||
if (m.canceled()) {
|
||||
throw tactic_exception(Z3_CANCELED_MSG);
|
||||
}
|
||||
throw tactic_exception(m_solver->reason_unknown().c_str());
|
||||
}
|
||||
m_solver->pop(1);
|
||||
}
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {
|
||||
m_solver->collect_statistics(st);
|
||||
}
|
||||
virtual void reset_statistics() {}
|
||||
|
||||
virtual void cleanup() {
|
||||
m_solver = m_solver->translate(m, m_params);
|
||||
}
|
||||
virtual void reset() { cleanup(); }
|
||||
|
||||
virtual void set_logic(symbol const & l) {}
|
||||
|
||||
virtual void set_progress_callback(progress_callback * callback) {
|
||||
m_solver->set_progress_callback(callback);
|
||||
}
|
||||
|
||||
virtual tactic * translate(ast_manager & m) {
|
||||
return alloc(solver2tactic, m_solver->translate(m, m_params));
|
||||
}
|
||||
};
|
||||
|
||||
tactic* mk_solver2tactic(solver* s) { return alloc(solver2tactic, s); }
|
30
src/solver/solver2tactic.h
Normal file
30
src/solver/solver2tactic.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*++
|
||||
Copyright (c) 2016 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
solver2tactic.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Convert solver to a tactic.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2016-10-17
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef SOLVER2TACTIC_H_
|
||||
#define SOLVER2TACTIC_H_
|
||||
|
||||
#include "tactic.h"
|
||||
#include "filter_model_converter.h"
|
||||
class solver;
|
||||
|
||||
tactic * mk_solver2tactic(solver* s);
|
||||
|
||||
void extract_clauses_and_dependencies(goal_ref const& g, expr_ref_vector& clauses, ptr_vector<expr>& assumptions, obj_map<expr, expr*>& bool2dep, ref<filter_model_converter>& fmc);
|
||||
|
||||
#endif
|
|
@ -160,6 +160,7 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass
|
|||
}
|
||||
}
|
||||
catch (z3_error & ex) {
|
||||
TRACE("tactic2solver", tout << "exception: " << ex.msg() << "\n";);
|
||||
throw ex;
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue