mirror of
https://github.com/Z3Prover/z3
synced 2025-04-06 17:44:08 +00:00
fix pickup of new constraints
This commit is contained in:
parent
1676378be9
commit
5c2a9d9936
|
@ -166,6 +166,7 @@ namespace sls {
|
|||
args.push_back(nsel->get_expr());
|
||||
}
|
||||
expr_ref f_map(m.mk_app(f, args), m);
|
||||
ctx.add_new_term(f_map);
|
||||
auto nsel = mk_select(g, n, sel);
|
||||
auto nmap = g.find(f_map);
|
||||
if (!nmap)
|
||||
|
@ -193,6 +194,7 @@ namespace sls {
|
|||
args.push_back(idx->get_expr());
|
||||
}
|
||||
expr_ref esel(a.mk_select(args), m);
|
||||
ctx.add_new_term(esel);
|
||||
auto n = g.find(esel);
|
||||
return n ? n : g.mk(esel, 0, eargs.size(), eargs.data());
|
||||
}
|
||||
|
@ -373,6 +375,11 @@ namespace sls {
|
|||
continue;
|
||||
if (p->get_arg(0)->get_root() != n->get_root())
|
||||
continue;
|
||||
#if 1
|
||||
bool is_relevant = any_of(euf::enode_class(p), [&](euf::enode* k) { return ctx.is_relevant(k->get_expr()); });
|
||||
if (!is_relevant)
|
||||
continue;
|
||||
#endif
|
||||
auto val = p->get_root();
|
||||
kv[n].insert(select_args(p), val);
|
||||
}
|
||||
|
|
|
@ -143,6 +143,7 @@ namespace sls {
|
|||
return l_undef;
|
||||
|
||||
if (all_of(m_plugins, [&](auto* p) { return !p || p->is_sat(); })) {
|
||||
VERIFY(unsat().empty() || !m_new_constraint);
|
||||
values2model();
|
||||
return l_true;
|
||||
}
|
||||
|
@ -184,11 +185,29 @@ namespace sls {
|
|||
throw default_exception("conflicting assignment");
|
||||
}
|
||||
}
|
||||
|
||||
validate_model(*mdl);
|
||||
|
||||
s.on_model(mdl);
|
||||
// verbose_stream() << *mdl << "\n";
|
||||
TRACE("sls", display(tout));
|
||||
}
|
||||
|
||||
void context::validate_model(model& mdl) {
|
||||
model_evaluator ev(mdl);
|
||||
for (sat::literal lit : root_literals()) {
|
||||
auto a = atom(lit.var());
|
||||
if (!a)
|
||||
continue;
|
||||
auto eval_a = ev(a);
|
||||
bool bad_model = (m.is_true(eval_a) && lit.sign()) || (m.is_false(eval_a) && !lit.sign());
|
||||
|
||||
if (bad_model) {
|
||||
IF_VERBOSE(0, verbose_stream() << lit << " " << a->get_id() << " " << mk_bounded_pp(a, m) << " " << eval_a << "\n");
|
||||
throw default_exception("failed to create a well-formed model");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void context::propagate_boolean_assignment() {
|
||||
start_propagation:
|
||||
|
@ -286,7 +305,7 @@ namespace sls {
|
|||
|
||||
bool context::is_true(expr* e) {
|
||||
SASSERT(m.is_bool(e));
|
||||
auto v = m_atom2bool_var.get(e->get_id(), sat::null_bool_var);
|
||||
auto v = m_atom2bool_var.get(e->get_id(), sat::null_bool_var);
|
||||
if (v != sat::null_bool_var)
|
||||
return is_true(v);
|
||||
if (m.is_and(e))
|
||||
|
@ -342,8 +361,10 @@ namespace sls {
|
|||
if (m_visited.contains(id))
|
||||
return false;
|
||||
m_visited.insert(id);
|
||||
if (m_parents.size() <= id)
|
||||
verbose_stream() << "not in map " << mk_bounded_pp(e, m) << "\n";
|
||||
if (m_parents.size() <= id) // expressions can be temporary created in E-graph but not registered
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (auto p : m_parents[id]) {
|
||||
if (is_relevant(p)) {
|
||||
m_relevant.insert(id);
|
||||
|
@ -353,18 +374,20 @@ namespace sls {
|
|||
return false;
|
||||
}
|
||||
|
||||
void context::add_constraint(expr* e) {
|
||||
bool context::add_constraint(expr* e) {
|
||||
if (m_constraint_ids.contains(e->get_id()))
|
||||
return;
|
||||
return false;
|
||||
m_constraint_ids.insert(e->get_id());
|
||||
m_constraint_trail.push_back(e);
|
||||
add_assertion(e, false);
|
||||
m_new_constraint = true;
|
||||
IF_VERBOSE(3, verbose_stream() << "add constraint " << mk_bounded_pp(e, m) << "\n");
|
||||
++m_stats.m_num_constraints;
|
||||
return true;
|
||||
}
|
||||
|
||||
void context::add_assertion(expr* f, bool is_input) {
|
||||
m_new_constraint = true;
|
||||
expr_ref _e(f, m);
|
||||
expr* g, * h, * k;
|
||||
sat::literal_vector clause;
|
||||
|
@ -676,7 +699,7 @@ namespace sls {
|
|||
has_relevant = true;
|
||||
break;
|
||||
}
|
||||
if (m_rand() % ++n == 0)
|
||||
if (m_rand(++n) == 0)
|
||||
selected_lit = lit;
|
||||
}
|
||||
if (!has_relevant && selected_lit != sat::null_literal) {
|
||||
|
|
|
@ -159,6 +159,8 @@ namespace sls {
|
|||
|
||||
|
||||
sat::literal mk_literal();
|
||||
|
||||
void validate_model(model& mdl);
|
||||
|
||||
public:
|
||||
context(ast_manager& m, sat_solver_context& s);
|
||||
|
@ -221,7 +223,7 @@ namespace sls {
|
|||
bool is_true(expr* e);
|
||||
bool is_fixed(expr* e);
|
||||
bool is_relevant(expr* e);
|
||||
void add_constraint(expr* e);
|
||||
bool add_constraint(expr* e);
|
||||
ptr_vector<expr> const& subterms();
|
||||
ast_manager& get_manager() { return m; }
|
||||
std::ostream& display(std::ostream& out) const;
|
||||
|
|
|
@ -52,11 +52,18 @@ namespace sls {
|
|||
void euf_plugin::register_term(expr* e) {
|
||||
if (!is_app(e))
|
||||
return;
|
||||
if (!is_uninterp(e))
|
||||
return;
|
||||
app* a = to_app(e);
|
||||
if (a->get_num_args() == 0)
|
||||
return;
|
||||
if (!is_uninterp(e)) {
|
||||
return;
|
||||
family_id fid = a->get_family_id();
|
||||
if (fid == basic_family_id)
|
||||
return;
|
||||
if (all_of(*a, [&](expr* arg) { return !is_app(arg) || fid == to_app(arg)->get_family_id(); }))
|
||||
return;
|
||||
}
|
||||
|
||||
auto f = a->get_decl();
|
||||
if (!m_app.contains(f))
|
||||
m_app.insert(f, ptr_vector<app>());
|
||||
|
@ -341,8 +348,8 @@ namespace sls {
|
|||
verbose_stream() << ctx.get_value(t->get_arg(i)) << " == " << ctx.get_value(u->get_arg(i)) << "\n";
|
||||
#endif
|
||||
expr_ref fml(m.mk_or(ors), m);
|
||||
ctx.add_constraint(fml);
|
||||
new_constraint = true;
|
||||
if (ctx.add_constraint(fml))
|
||||
new_constraint = true;
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -368,8 +375,8 @@ namespace sls {
|
|||
}
|
||||
// distinct(a, b, c) or a = b or a = c or b = c
|
||||
eqs.push_back(e);
|
||||
ctx.add_constraint(m.mk_or(eqs));
|
||||
new_constraint = true;
|
||||
if (ctx.add_constraint(m.mk_or(eqs)))
|
||||
new_constraint = true;
|
||||
done_distinct:
|
||||
;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue