3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-25 00:12:34 +00:00

prepare ground for general projection

This commit is contained in:
Nikolaj Bjorner 2026-07-12 15:59:32 -07:00
parent eaceded5f1
commit bcc176fc47
7 changed files with 170 additions and 77 deletions

View file

@ -668,53 +668,7 @@ namespace smt {
auto &st = m_ho_state;
auto *hoq = st.m_q;
auto *q = m_ho_matcher->hoq2q(hoq);
expr_ref_vector binding(m);
for (unsigned i = 0; i < s.size(); ++i)
binding.push_back(s.get(i));
// Shrink binding to original quantifier's num_decls
// The HO quantifier has extra vars at higher indices; drop them.
// Binding is indexed by var index: binding[i] = value for var i.
// First substitute any remaining vars, then keep only original vars.
TRACE(
ho_matching, tout << "num bound variables " << q->get_num_decls() << " for " << mk_bounded_pp(q, m)
<< "\n"
<< binding << "\n";
for (unsigned i = 0; i < binding.size(); ++i) {
tout << i << " - " << mk_pp(binding.get(i)->get_sort(), m) << ": " << mk_ll_pp(binding.get(i), m)
<< "\n";
});
if (binding.size() > q->get_num_decls()) {
// binding is indexed directly (binding[k] = value for var k),
// so the substitution must use direct (non-standard) order to
// resolve chained HO variable references; the sort guard below
// is checked with the matching order.
var_subst sub(m, false);
bool change = true;
while (change) {
change = false;
for (unsigned i = 0; i < binding.size(); ++i) {
if (!binding.get(i))
continue;
// A misaligned higher-order binding would build an
// ill-sorted term. Abandon this refinement (no instance)
// rather than aborting the whole solve.
SASSERT(is_well_sorted(m, binding.get(i)));
auto r = sub(binding.get(i), binding);
change |= r != binding.get(i);
binding[i] = r;
SASSERT(is_well_sorted(m, binding.get(i)));
TRACE(ho_matching, tout << "setting v" << i << " <- " << r << "\n");
}
}
binding.shrink(q->get_num_decls());
}
if (binding.size() < q->get_num_decls())
return;
binding.reverse();
auto const &binding = s.get_binding(q);
st.m_matches.push_back({ q, binding });
}

View file

@ -371,14 +371,14 @@ namespace smt {
else {
if (mk_interface_eqs_at_final_check() == FC_CONTINUE)
r = FC_CONTINUE;
else
else
r = assert_delayed_axioms();
}
}
else {
if (m_final_check_idx % 2 == 1) {
r = assert_delayed_axioms();
if (r == FC_DONE)
if (r == FC_DONE)
r = mk_interface_eqs_at_final_check();
}
else {
@ -389,7 +389,7 @@ namespace smt {
}
}
bool should_giveup = m_found_unsupported_op || has_propagate_up_trail();
if (r == FC_DONE && should_giveup && !ctx.get_fparams().m_array_fake_support)
if (r == FC_DONE && should_giveup && !ctx.get_fparams().m_array_fake_support)
r = FC_GIVEUP;
CTRACE(array, r != FC_DONE || m_found_unsupported_op, tout << r << "\n";);
return r;

View file

@ -712,6 +712,7 @@ namespace smt {
collect_defaults();
collect_selects();
propagate_selects();
TRACE(array, display_selects(tout); display(tout););
}
/**
@ -809,12 +810,28 @@ namespace smt {
return set;
}
void theory_array_base::collect_selects() {
int num_vars = get_num_vars();
void theory_array_base::reset_selects() {
for (auto r : m_selects_range)
dealloc(r);
m_selects_range.reset();
m_selects.reset();
m_selects_domain.reset();
m_selects_range.reset();
}
std::ostream& theory_array_base::display_selects(std::ostream& out) {
for (auto [r, s] : m_selects) {
tout << enode_pp(r, ctx) << ":\n";
for (auto sel : *s)
tout << " " << enode_pp(sel, ctx) << " "
<< enode_pp(sel->get_root(), ctx) << "\n";
tout << "\n";
}
return out;
}
void theory_array_base::collect_selects() {
int num_vars = get_num_vars();
reset_selects();
for (theory_var v = 0; v < num_vars; ++v) {
enode * r = get_enode(v)->get_root();
@ -889,7 +906,7 @@ namespace smt {
}
void theory_array_base::finalize_model(model_generator & m) {
std::for_each(m_selects_range.begin(), m_selects_range.end(), delete_proc<select_set>());
reset_selects();
}
class array_value_proc : public model_value_proc {

View file

@ -191,6 +191,9 @@ namespace smt {
ptr_vector<select_set> m_selects_range;
bool m_use_unspecified_default; // temporary field for model construction
void reset_selects();
std::ostream &display_selects(std::ostream &out);
theory_var mg_find(theory_var v);
void mg_merge(theory_var n, theory_var m);