mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
enable unsat core extraction in nlsat_tactic
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
84172302a2
commit
305e080239
|
@ -1283,7 +1283,7 @@ namespace nlsat {
|
||||||
if (r == l_false) {
|
if (r == l_false) {
|
||||||
// collect used literals from m_lemma_assumptions
|
// collect used literals from m_lemma_assumptions
|
||||||
vector<assumption, false> deps;
|
vector<assumption, false> deps;
|
||||||
m_asm.linearize(m_lemma_assumptions.get(), deps);
|
get_core(deps);
|
||||||
for (unsigned i = 0; i < deps.size(); ++i) {
|
for (unsigned i = 0; i < deps.size(); ++i) {
|
||||||
literal const* lp = (literal const*)(deps[i]);
|
literal const* lp = (literal const*)(deps[i]);
|
||||||
if (ptr <= lp && lp < ptr + sz) {
|
if (ptr <= lp && lp < ptr + sz) {
|
||||||
|
@ -1299,6 +1299,10 @@ namespace nlsat {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_core(vector<assumption, false>& deps) {
|
||||||
|
m_asm.linearize(m_lemma_assumptions.get(), deps);
|
||||||
|
}
|
||||||
|
|
||||||
void collect(literal_vector const& assumptions, clause_vector& clauses) {
|
void collect(literal_vector const& assumptions, clause_vector& clauses) {
|
||||||
unsigned n = clauses.size();
|
unsigned n = clauses.size();
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
|
@ -2712,6 +2716,10 @@ namespace nlsat {
|
||||||
return m_imp->check(assumptions);
|
return m_imp->check(assumptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solver::get_core(vector<assumption, false>& assumptions) {
|
||||||
|
return m_imp->get_core(assumptions);
|
||||||
|
}
|
||||||
|
|
||||||
void solver::reset() {
|
void solver::reset() {
|
||||||
m_imp->reset();
|
m_imp->reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,6 +195,14 @@ namespace nlsat {
|
||||||
|
|
||||||
lbool value(literal l) const;
|
lbool value(literal l) const;
|
||||||
|
|
||||||
|
// -----------------------
|
||||||
|
//
|
||||||
|
// Core
|
||||||
|
//
|
||||||
|
// -----------------------
|
||||||
|
|
||||||
|
void get_core(vector<assumption, false>& deps);
|
||||||
|
|
||||||
// -----------------------
|
// -----------------------
|
||||||
//
|
//
|
||||||
// Misc
|
// Misc
|
||||||
|
|
|
@ -147,6 +147,7 @@ class nlsat_tactic : public tactic {
|
||||||
TRACE("nlsat", g->display(tout););
|
TRACE("nlsat", g->display(tout););
|
||||||
expr2var a2b(m);
|
expr2var a2b(m);
|
||||||
expr2var t2x(m);
|
expr2var t2x(m);
|
||||||
|
|
||||||
m_g2nl(*g, m_params, m_solver, a2b, t2x);
|
m_g2nl(*g, m_params, m_solver, a2b, t2x);
|
||||||
|
|
||||||
m_display_var.m_var2expr.reset();
|
m_display_var.m_var2expr.reset();
|
||||||
|
@ -172,9 +173,19 @@ class nlsat_tactic : public tactic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: extract unsat core
|
expr_dependency* lcore = 0;
|
||||||
g->assert_expr(m.mk_false(), 0, 0);
|
if (g->unsat_core_enabled()) {
|
||||||
|
vector<nlsat::assumption, false> assumptions;
|
||||||
|
m_solver.get_core(assumptions);
|
||||||
|
for (unsigned i = 0; i < assumptions.size(); ++i) {
|
||||||
|
expr_dependency* d = static_cast<expr_dependency*>(assumptions[i]);
|
||||||
|
lcore = m.mk_join(lcore, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g->assert_expr(m.mk_false(), 0, lcore);
|
||||||
|
core = lcore;
|
||||||
}
|
}
|
||||||
|
|
||||||
g->inc_depth();
|
g->inc_depth();
|
||||||
result.push_back(g.get());
|
result.push_back(g.get());
|
||||||
TRACE("nlsat", g->display(tout););
|
TRACE("nlsat", g->display(tout););
|
||||||
|
|
|
@ -73,14 +73,15 @@ class sat_tactic : public tactic {
|
||||||
if (r == l_false) {
|
if (r == l_false) {
|
||||||
expr_dependency * lcore = 0;
|
expr_dependency * lcore = 0;
|
||||||
if (produce_core) {
|
if (produce_core) {
|
||||||
sat::literal_vector const& core = m_solver.get_core();
|
sat::literal_vector const& ucore = m_solver.get_core();
|
||||||
u_map<expr*> asm2dep;
|
u_map<expr*> asm2dep;
|
||||||
mk_asm2dep(dep2asm, asm2dep);
|
mk_asm2dep(dep2asm, asm2dep);
|
||||||
for (unsigned i = 0; i < core.size(); ++i) {
|
for (unsigned i = 0; i < ucore.size(); ++i) {
|
||||||
sat::literal lit = core[i];
|
sat::literal lit = ucore[i];
|
||||||
expr* dep = asm2dep.find(lit.index());
|
expr* dep = asm2dep.find(lit.index());
|
||||||
lcore = m.mk_join(lcore, m.mk_leaf(dep));
|
lcore = m.mk_join(lcore, m.mk_leaf(dep));
|
||||||
}
|
}
|
||||||
|
core = lcore;
|
||||||
}
|
}
|
||||||
g->assert_expr(m.mk_false(), 0, lcore);
|
g->assert_expr(m.mk_false(), 0, lcore);
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,7 @@ public:
|
||||||
proof_converter_ref & pc,
|
proof_converter_ref & pc,
|
||||||
expr_dependency_ref & core) {
|
expr_dependency_ref & core) {
|
||||||
try {
|
try {
|
||||||
|
mc = 0; pc = 0; core = 0;
|
||||||
SASSERT(in->is_well_sorted());
|
SASSERT(in->is_well_sorted());
|
||||||
ast_manager & m = in->m();
|
ast_manager & m = in->m();
|
||||||
TRACE("smt_tactic", tout << this << "\nAUTO_CONFIG: " << fparams().m_auto_config << " HIDIV0: " << fparams().m_hi_div0 << " "
|
TRACE("smt_tactic", tout << this << "\nAUTO_CONFIG: " << fparams().m_auto_config << " HIDIV0: " << fparams().m_hi_div0 << " "
|
||||||
|
@ -206,8 +207,6 @@ public:
|
||||||
mc = model2model_converter(md.get());
|
mc = model2model_converter(md.get());
|
||||||
mc = concat(fmc.get(), mc.get());
|
mc = concat(fmc.get(), mc.get());
|
||||||
}
|
}
|
||||||
pc = 0;
|
|
||||||
core = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case l_false: {
|
case l_false: {
|
||||||
|
@ -229,12 +228,10 @@ public:
|
||||||
expr * d = bool2dep.find(b);
|
expr * d = bool2dep.find(b);
|
||||||
lcore = m.mk_join(lcore, m.mk_leaf(d));
|
lcore = m.mk_join(lcore, m.mk_leaf(d));
|
||||||
}
|
}
|
||||||
|
core = lcore;
|
||||||
}
|
}
|
||||||
in->assert_expr(m.mk_false(), pr, lcore);
|
in->assert_expr(m.mk_false(), pr, lcore);
|
||||||
result.push_back(in.get());
|
result.push_back(in.get());
|
||||||
mc = 0;
|
|
||||||
pc = 0;
|
|
||||||
core = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case l_undef:
|
case l_undef:
|
||||||
|
@ -257,8 +254,6 @@ public:
|
||||||
m_ctx->get_model(md);
|
m_ctx->get_model(md);
|
||||||
mc = model2model_converter(md.get());
|
mc = model2model_converter(md.get());
|
||||||
}
|
}
|
||||||
pc = 0;
|
|
||||||
core = 0;
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -105,6 +105,7 @@ public:
|
||||||
/* out */ model_converter_ref & mc,
|
/* out */ model_converter_ref & mc,
|
||||||
/* out */ proof_converter_ref & pc,
|
/* out */ proof_converter_ref & pc,
|
||||||
/* out */ expr_dependency_ref & core) {
|
/* out */ expr_dependency_ref & core) {
|
||||||
|
pc = 0; mc = 0; core = 0;
|
||||||
expr_ref_vector clauses(m);
|
expr_ref_vector clauses(m);
|
||||||
expr2expr_map bool2dep;
|
expr2expr_map bool2dep;
|
||||||
ptr_vector<expr> assumptions;
|
ptr_vector<expr> assumptions;
|
||||||
|
@ -123,8 +124,6 @@ public:
|
||||||
}
|
}
|
||||||
in->reset();
|
in->reset();
|
||||||
result.push_back(in.get());
|
result.push_back(in.get());
|
||||||
pc = 0;
|
|
||||||
core = 0;
|
|
||||||
break;
|
break;
|
||||||
case l_false: {
|
case l_false: {
|
||||||
in->reset();
|
in->reset();
|
||||||
|
@ -132,6 +131,7 @@ public:
|
||||||
expr_dependency* lcore = 0;
|
expr_dependency* lcore = 0;
|
||||||
if (in->proofs_enabled()) {
|
if (in->proofs_enabled()) {
|
||||||
pr = local_solver->get_proof();
|
pr = local_solver->get_proof();
|
||||||
|
pc = proof2proof_converter(m, pr);
|
||||||
}
|
}
|
||||||
if (in->unsat_core_enabled()) {
|
if (in->unsat_core_enabled()) {
|
||||||
ptr_vector<expr> core;
|
ptr_vector<expr> core;
|
||||||
|
@ -142,9 +142,7 @@ public:
|
||||||
}
|
}
|
||||||
in->assert_expr(m.mk_false(), pr, lcore);
|
in->assert_expr(m.mk_false(), pr, lcore);
|
||||||
result.push_back(in.get());
|
result.push_back(in.get());
|
||||||
mc = 0;
|
core = lcore;
|
||||||
pc = 0;
|
|
||||||
core = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case l_undef:
|
case l_undef:
|
||||||
|
|
|
@ -137,7 +137,9 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass
|
||||||
g->assert_expr(m_assertions.get(i));
|
g->assert_expr(m_assertions.get(i));
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < num_assumptions; i++) {
|
for (unsigned i = 0; i < num_assumptions; i++) {
|
||||||
g->assert_expr(assumptions[i], m.mk_asserted(assumptions[i]), m.mk_leaf(assumptions[i]));
|
proof_ref pr(m.mk_asserted(assumptions[i]), m);
|
||||||
|
expr_dependency_ref ans(m.mk_leaf(assumptions[i]), m);
|
||||||
|
g->assert_expr(assumptions[i], pr, ans);
|
||||||
}
|
}
|
||||||
|
|
||||||
model_ref md;
|
model_ref md;
|
||||||
|
|
|
@ -237,6 +237,9 @@ void goal::slow_process(expr * f, proof * pr, expr_dependency * d) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void goal::assert_expr(expr * f, proof * pr, expr_dependency * d) {
|
void goal::assert_expr(expr * f, proof * pr, expr_dependency * d) {
|
||||||
|
expr_ref _f(f, m());
|
||||||
|
proof_ref _pr(pr, m());
|
||||||
|
expr_dependency_ref _d(d, m());
|
||||||
SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
|
SASSERT(proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
|
||||||
if (m_inconsistent)
|
if (m_inconsistent)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -200,7 +200,7 @@ static void test_sorting_eq(unsigned n, unsigned k) {
|
||||||
// equality:
|
// equality:
|
||||||
std::cout << "eq " << k << "\n";
|
std::cout << "eq " << k << "\n";
|
||||||
solver.push();
|
solver.push();
|
||||||
result = sn.eq(k, in.size(), in.c_ptr());
|
result = sn.eq(true, k, in.size(), in.c_ptr());
|
||||||
solver.assert_expr(result);
|
solver.assert_expr(result);
|
||||||
for (unsigned i = 0; i < ext.m_clauses.size(); ++i) {
|
for (unsigned i = 0; i < ext.m_clauses.size(); ++i) {
|
||||||
solver.assert_expr(ext.m_clauses[i].get());
|
solver.assert_expr(ext.m_clauses[i].get());
|
||||||
|
|
Loading…
Reference in a new issue