3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-18 02:16:40 +00:00

fix unsoundness in quantifier propagation #6116 and add initial lemma logging

This commit is contained in:
Nikolaj Bjorner 2022-08-23 19:09:50 -07:00
parent 912b284602
commit ce1f3987d9
15 changed files with 78 additions and 13 deletions

View file

@ -16,6 +16,8 @@ Author:
--*/
#include "sat/smt/euf_solver.h"
#include "ast/ast_util.h"
#include <iostream>
namespace euf {
@ -192,4 +194,23 @@ namespace euf {
get_drat().bool_def(lit.var(), eq->get_id());
}
void solver::log_clause(unsigned n, literal const* lits, sat::status st) {
if (get_config().m_lemmas2console) {
std::function<symbol(int)> ppth = [&](int th) {
return m.get_family_name(th);
};
if (st.is_redundant() || st.is_asserted()) {
expr_ref_vector clause(m);
for (unsigned i = 0; i < n; ++i) {
expr_ref e = literal2expr(lits[i]);
if (!e)
return;
clause.push_back(e);
}
expr_ref cl = mk_or(clause);
std::cout << sat::status_pp(st, ppth) << " " << cl << "\n";
}
}
}
}

View file

@ -169,6 +169,14 @@ namespace euf {
TRACE("before_search", s().display(tout););
for (auto* s : m_solvers)
s->init_search();
if (get_config().m_lemmas2console) {
std::function<void(unsigned, sat::literal const*, sat::status)> on_clause =
[&](unsigned n, sat::literal const* lits, sat::status st) {
log_clause(n, lits, st);
};
get_drat().set_print_clause(on_clause);
}
}
bool solver::is_external(bool_var v) {

View file

@ -182,6 +182,7 @@ namespace euf {
obj_hashtable<ast> m_drat_asts;
bool m_drat_initialized{ false };
void init_drat();
void log_clause(unsigned n, literal const* lits, sat::status st);
// relevancy
//bool_vector m_relevant_expr_ids;

View file

@ -379,9 +379,14 @@ namespace q {
else {
++m_stats.m_num_propagations;
auto& j = justification::from_index(j_idx);
auto lit = instantiate(j.m_clause, j.m_binding, j.m_clause[idx]);
ctx.propagate(lit, j_idx);
sat::literal_vector lits;
lits.push_back(~j.m_clause.m_literal);
for (unsigned i = 0; i < j.m_clause.size(); ++i)
lits.push_back(instantiate(j.m_clause, j.m_binding, j.m_clause[i]));
m_qs.log_instantiation(lits);
m_qs.add_clause(lits);
}
}
bool ematch::flush_prop_queue() {
@ -408,6 +413,7 @@ namespace q {
void ematch::add_instantiation(clause& c, binding& b, sat::literal lit) {
m_evidence.reset();
ctx.propagate(lit, mk_justification(UINT_MAX, c, b.nodes()));
m_qs.log_instantiation(~c.m_literal, lit);
}
sat::literal ematch::instantiate(clause& c, euf::enode* const* binding, lit const& l) {

View file

@ -47,21 +47,21 @@ namespace q {
unsigned lim = m_indirect_nodes.size();
lit l = c[i];
lbool cmp = compare(n, binding, l.lhs, l.rhs, evidence);
TRACE("q", tout << l.lhs << " ~~ " << l.rhs << " is " << cmp << "\n";);
switch (cmp) {
case l_false:
case l_false:
m_indirect_nodes.shrink(lim);
if (!l.sign)
break;
c.m_watch = i;
return l_true;
case l_true:
case l_true:
m_indirect_nodes.shrink(lim);
if (l.sign)
break;
break;
c.m_watch = i;
return l_true;
case l_undef:
TRACE("q", tout << l.lhs << " ~~ " << l.rhs << " is undef\n";);
if (idx != UINT_MAX) {
idx = UINT_MAX;
return l_undef;

View file

@ -71,6 +71,7 @@ namespace q {
for (auto const& [qlit, fml, generation] : m_instantiations) {
euf::solver::scoped_generation sg(ctx, generation + 1);
sat::literal lit = ctx.mk_literal(fml);
m_qs.log_instantiation(~qlit, ~lit);
m_qs.add_clause(~qlit, ~lit);
}
m_instantiations.reset();

View file

@ -356,4 +356,7 @@ namespace q {
m_ematch.get_antecedents(l, idx, r, probing);
}
void solver::log_instantiation(unsigned n, sat::literal const* lits) {
TRACE("q", for (unsigned i = 0; i < n; ++i) tout << literal2expr(lits[i]) << "\n";);
}
}

View file

@ -88,5 +88,9 @@ namespace q {
sat::literal_vector const& universal() const { return m_universal; }
quantifier* flatten(quantifier* q);
void log_instantiation(sat::literal q, sat::literal i) { sat::literal lits[2] = { q, i }; log_instantiation(2, lits); }
void log_instantiation(sat::literal_vector const& lits) { log_instantiation(lits.size(), lits.data()); }
void log_instantiation(unsigned n, sat::literal const* lits);
};
}