3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-23 12:48:53 +00:00

fixes in new solver

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-12-25 11:19:31 -08:00
parent 21c626e3ee
commit 372e5ca569
12 changed files with 79 additions and 43 deletions

View file

@ -672,6 +672,9 @@ namespace euf {
out << " " << p->get_expr_id(); out << " " << p->get_expr_id();
out << "] "; out << "] ";
} }
if (n->value() != l_undef) {
out << "[v" << n->bool_var() << " := " << (n->value() == l_true ? "T":"F") << "] ";
}
if (n->has_th_vars()) { if (n->has_th_vars()) {
out << "[t"; out << "[t";
for (auto v : enode_th_vars(n)) for (auto v : enode_th_vars(n))

View file

@ -1462,7 +1462,6 @@ void core::check_weighted(unsigned sz, std::pair<unsigned, std::function<void(vo
bound += checks[i].first; bound += checks[i].first;
uint_set seen; uint_set seen;
while (bound > 0 && !done() && m_lemma_vec->empty()) { while (bound > 0 && !done() && m_lemma_vec->empty()) {
SASSERT(bound > 0);
unsigned n = random() % bound; unsigned n = random() % bound;
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
if (seen.contains(i)) if (seen.contains(i))

View file

@ -56,7 +56,7 @@ namespace arith {
scoped_anum an(m_nla->am()); scoped_anum an(m_nla->am());
m_nla->am().display(out << " = ", nl_value(v, an)); m_nla->am().display(out << " = ", nl_value(v, an));
} }
else if (m_model_is_initialized && is_registered_var(v)) else if (can_get_value(v))
out << " = " << get_value(v); out << " = " << get_value(v);
if (is_int(v)) if (is_int(v))
out << ", int"; out << ", int";

View file

@ -84,6 +84,7 @@ namespace arith {
} }
bool solver::unit_propagate() { bool solver::unit_propagate() {
m_model_is_initialized = false;
if (!m_new_eq && m_new_bounds.empty() && m_asserted_qhead == m_asserted.size()) if (!m_new_eq && m_new_bounds.empty() && m_asserted_qhead == m_asserted.size())
return false; return false;
@ -572,6 +573,10 @@ namespace arith {
value = ~value; value = ~value;
if (!found_bad && value == get_phase(n->bool_var())) if (!found_bad && value == get_phase(n->bool_var()))
continue; continue;
TRACE("arith",
tout << eval << " " << value << " " << ctx.bpp(n) << "\n";
tout << mdl << "\n";
s().display(tout););
IF_VERBOSE(0, IF_VERBOSE(0,
verbose_stream() << eval << " " << value << " " << ctx.bpp(n) << "\n"; verbose_stream() << eval << " " << value << " " << ctx.bpp(n) << "\n";
verbose_stream() << n->bool_var() << " " << n->value() << " " << get_phase(n->bool_var()) << " " << ctx.bpp(n) << "\n"; verbose_stream() << n->bool_var() << " " << n->value() << " " << get_phase(n->bool_var()) << " " << ctx.bpp(n) << "\n";
@ -642,6 +647,7 @@ namespace arith {
for (unsigned i = m_bounds_trail.size(); i-- > old_size; ) { for (unsigned i = m_bounds_trail.size(); i-- > old_size; ) {
unsigned v = m_bounds_trail[i]; unsigned v = m_bounds_trail[i];
api_bound* b = m_bounds[v].back(); api_bound* b = m_bounds[v].back();
m_bool_var2bound.erase(b->get_lit().var());
// del_use_lists(b); // del_use_lists(b);
dealloc(b); dealloc(b);
m_bounds[v].pop_back(); m_bounds[v].pop_back();

View file

@ -318,6 +318,9 @@ namespace arith {
vector<constraint_bound> m_upper_terms; vector<constraint_bound> m_upper_terms;
vector<constraint_bound> m_history; vector<constraint_bound> m_history;
bool can_get_value(theory_var v) const {
return is_registered_var(v) && m_model_is_initialized;
}
// solving // solving
void report_equality_of_fixed_vars(unsigned vi1, unsigned vi2); void report_equality_of_fixed_vars(unsigned vi1, unsigned vi2);

View file

@ -22,51 +22,6 @@ Author:
namespace euf { namespace euf {
void solver::update_model(model_ref& mdl) {
for (auto* mb : m_solvers)
mb->init_model();
deps_t deps;
m_values.reset();
m_values2root.reset();
collect_dependencies(deps);
deps.topological_sort();
dependencies2values(deps, mdl);
values2model(deps, mdl);
for (auto* mb : m_solvers)
mb->finalize_model(*mdl);
// validate_model(*mdl);
}
bool solver::include_func_interp(func_decl* f) {
if (f->is_skolem())
return false;
if (f->get_family_id() == null_family_id)
return true;
if (f->get_family_id() == m.get_basic_family_id())
return false;
euf::th_model_builder* mb = func_decl2solver(f);
return mb && mb->include_func_interp(f);
}
void solver::collect_dependencies(deps_t& deps) {
for (enode* n : m_egraph.nodes()) {
auto* mb = sort2solver(m.get_sort(n->get_expr()));
if (mb)
mb->add_dep(n, deps);
else
deps.insert(n, nullptr);
}
TRACE("euf",
for (auto const& d : deps.deps())
if (d.m_value) {
tout << mk_bounded_pp(d.m_key->get_expr(), m) << ":\n";
for (auto* n : *d.m_value)
tout << " " << mk_bounded_pp(n->get_expr(), m) << "\n";
}
);
}
class solver::user_sort { class solver::user_sort {
ast_manager& m; ast_manager& m;
model_ref& mdl; model_ref& mdl;
@ -94,10 +49,63 @@ namespace euf {
} }
vals->push_back(value); vals->push_back(value);
} }
void register_value(expr* val) {
factory.register_value(val);
}
}; };
void solver::dependencies2values(deps_t& deps, model_ref& mdl) { void solver::update_model(model_ref& mdl) {
user_sort user_sort(*this, m_values, mdl); for (auto* mb : m_solvers)
mb->init_model();
deps_t deps;
m_values.reset();
m_values2root.reset();
user_sort us(*this, m_values, mdl);
collect_dependencies(us, deps);
deps.topological_sort();
dependencies2values(us, deps, mdl);
values2model(deps, mdl);
for (auto* mb : m_solvers)
mb->finalize_model(*mdl);
// validate_model(*mdl);
}
bool solver::include_func_interp(func_decl* f) {
if (f->is_skolem())
return false;
if (f->get_family_id() == null_family_id)
return true;
if (f->get_family_id() == m.get_basic_family_id())
return false;
euf::th_model_builder* mb = func_decl2solver(f);
return mb && mb->include_func_interp(f);
}
void solver::collect_dependencies(user_sort& us, deps_t& deps) {
for (enode* n : m_egraph.nodes()) {
expr* e = n->get_expr();
sort* srt = m.get_sort(e);
auto* mb = sort2solver(srt);
if (mb)
mb->add_dep(n, deps);
else
deps.insert(n, nullptr);
if (n->is_root() && m.is_uninterp(srt) && m.is_value(e))
us.register_value(e);
}
TRACE("euf",
for (auto const& d : deps.deps())
if (d.m_value) {
tout << mk_bounded_pp(d.m_key->get_expr(), m) << ":\n";
for (auto* n : *d.m_value)
tout << " " << mk_bounded_pp(n->get_expr(), m) << "\n";
}
);
}
void solver::dependencies2values(user_sort& us, deps_t& deps, model_ref& mdl) {
for (enode* n : deps.top_sorted()) { for (enode* n : deps.top_sorted()) {
unsigned id = n->get_root_id(); unsigned id = n->get_root_id();
if (m_values.get(id, nullptr)) if (m_values.get(id, nullptr))
@ -134,9 +142,13 @@ namespace euf {
} }
continue; continue;
} }
if (m.is_value(n->get_root()->get_expr())) {
m_values.set(id, n->get_root()->get_expr());
continue;
}
sort* srt = m.get_sort(e); sort* srt = m.get_sort(e);
if (m.is_uninterp(srt)) if (m.is_uninterp(srt))
user_sort.add(id, srt); us.add(id, srt);
else if (auto* mbS = sort2solver(srt)) else if (auto* mbS = sort2solver(srt))
mbS->add_value(n, *mdl, m_values); mbS->add_value(n, *mdl, m_values);
else if (auto* mbE = expr2solver(e)) else if (auto* mbE = expr2solver(e))

View file

@ -137,6 +137,8 @@ namespace euf {
void solver::unhandled_function(func_decl* f) { void solver::unhandled_function(func_decl* f) {
if (m_unhandled_functions.contains(f)) if (m_unhandled_functions.contains(f))
return; return;
if (m.is_model_value(f))
return;
m_unhandled_functions.push_back(f); m_unhandled_functions.push_back(f);
m_trail.push(push_back_vector<solver, func_decl_ref_vector>(m_unhandled_functions)); m_trail.push(push_back_vector<solver, func_decl_ref_vector>(m_unhandled_functions));
IF_VERBOSE(0, verbose_stream() << mk_pp(f, m) << " not handled\n"); IF_VERBOSE(0, verbose_stream() << mk_pp(f, m) << " not handled\n");

View file

@ -141,8 +141,8 @@ namespace euf {
obj_map<expr, enode*> m_values2root; obj_map<expr, enode*> m_values2root;
bool include_func_interp(func_decl* f); bool include_func_interp(func_decl* f);
void register_macros(model& mdl); void register_macros(model& mdl);
void dependencies2values(deps_t& deps, model_ref& mdl); void dependencies2values(user_sort& us, deps_t& deps, model_ref& mdl);
void collect_dependencies(deps_t& deps); void collect_dependencies(user_sort& us, deps_t& deps);
void values2model(deps_t const& deps, model_ref& mdl); void values2model(deps_t const& deps, model_ref& mdl);
void validate_model(model& mdl); void validate_model(model& mdl);

View file

@ -99,13 +99,13 @@ namespace q {
lbool mbqi::check_forall(quantifier* q) { lbool mbqi::check_forall(quantifier* q) {
quantifier* q_flat = m_qs.flatten(q); quantifier* q_flat = m_qs.flatten(q);
init_solver();
::solver::scoped_push _sp(*m_solver);
auto* qb = specialize(q_flat); auto* qb = specialize(q_flat);
if (!qb) if (!qb)
return l_undef; return l_undef;
if (m.is_false(qb->mbody)) if (m.is_false(qb->mbody))
return l_true; return l_true;
init_solver();
::solver::scoped_push _sp(*m_solver);
m_solver->assert_expr(qb->mbody); m_solver->assert_expr(qb->mbody);
lbool r = m_solver->check_sat(0, nullptr); lbool r = m_solver->check_sat(0, nullptr);
if (r == l_undef) if (r == l_undef)

View file

@ -33,6 +33,7 @@ namespace sat {
m_roots.push_scope(); m_roots.push_scope();
m_tracked_vars.push_scope(); m_tracked_vars.push_scope();
m_units.push_scope(); m_units.push_scope();
m_vars.push_scope();
} }
void dual_solver::pop(unsigned num_scopes) { void dual_solver::pop(unsigned num_scopes) {
@ -40,6 +41,14 @@ namespace sat {
unsigned old_sz = m_tracked_vars.old_size(num_scopes); unsigned old_sz = m_tracked_vars.old_size(num_scopes);
for (unsigned i = m_tracked_vars.size(); i-- > old_sz; ) for (unsigned i = m_tracked_vars.size(); i-- > old_sz; )
m_is_tracked[m_tracked_vars[i]] = false; m_is_tracked[m_tracked_vars[i]] = false;
old_sz = m_vars.old_size(num_scopes);
for (unsigned i = m_vars.size(); i-- > old_sz; ) {
unsigned v = m_vars[i];
unsigned w = m_ext2var[v];
m_ext2var[v] = null_bool_var;
m_var2ext[w] = null_bool_var;
}
m_vars.pop_scope(num_scopes);
m_units.pop_scope(num_scopes); m_units.pop_scope(num_scopes);
m_roots.pop_scope(num_scopes); m_roots.pop_scope(num_scopes);
m_tracked_vars.pop_scope(num_scopes); m_tracked_vars.pop_scope(num_scopes);
@ -51,6 +60,7 @@ namespace sat {
w = m_solver.mk_var(); w = m_solver.mk_var();
m_ext2var.setx(v, w, null_bool_var); m_ext2var.setx(v, w, null_bool_var);
m_var2ext.setx(w, v, null_bool_var); m_var2ext.setx(w, v, null_bool_var);
m_vars.push_back(v);
} }
return w; return w;
} }

View file

@ -34,6 +34,7 @@ namespace sat {
bool_var_vector m_is_tracked; bool_var_vector m_is_tracked;
unsigned_vector m_ext2var; unsigned_vector m_ext2var;
unsigned_vector m_var2ext; unsigned_vector m_var2ext;
lim_svector<unsigned> m_vars;
void add_literal(literal lit); void add_literal(literal lit);
bool_var ext2var(bool_var v); bool_var ext2var(bool_var v);