mirror of
https://github.com/Z3Prover/z3
synced 2025-08-14 23:05:26 +00:00
working on ho-matcher
This commit is contained in:
parent
195f3c9110
commit
35b1d09425
4 changed files with 49 additions and 22 deletions
|
@ -636,15 +636,15 @@ namespace euf {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
quantifier* ho_matcher::compile_ho_pattern(quantifier* q, app*& p) {
|
std::pair<quantifier*, app*> ho_matcher::compile_ho_pattern(quantifier* q, app* p) {
|
||||||
app* p1 = nullptr;
|
app* p1 = nullptr;
|
||||||
if (m_pat2hopat.find(p, p)) {
|
if (m_pat2hopat.find(p, p)) {
|
||||||
q = m_q2hoq[q];
|
q = m_q2hoq[q];
|
||||||
return q;
|
return { q, p };
|
||||||
}
|
}
|
||||||
auto is_ho = any_of(subterms::all(expr_ref(p, m)), [&](expr* t) { return m_unitary.is_flex(0, t); });
|
auto is_ho = any_of(subterms::all(expr_ref(p, m)), [&](expr* t) { return m_unitary.is_flex(0, t); });
|
||||||
if (!is_ho)
|
if (!is_ho)
|
||||||
return q;
|
return { q, p };
|
||||||
ptr_vector<expr> todo;
|
ptr_vector<expr> todo;
|
||||||
ptr_buffer<var> bound;
|
ptr_buffer<var> bound;
|
||||||
expr_ref_vector cache(m);
|
expr_ref_vector cache(m);
|
||||||
|
@ -684,7 +684,7 @@ namespace euf {
|
||||||
}
|
}
|
||||||
if (is_quantifier(t)) {
|
if (is_quantifier(t)) {
|
||||||
m_pat2abs.remove(p);
|
m_pat2abs.remove(p);
|
||||||
return q;
|
return { q, p };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p1 = to_app(cache.get(p->get_id()));
|
p1 = to_app(cache.get(p->get_id()));
|
||||||
|
@ -739,8 +739,7 @@ namespace euf {
|
||||||
trail().push(insert_map(m_q2hoq, q));
|
trail().push(insert_map(m_q2hoq, q));
|
||||||
trail().push(insert_map(m_hoq2q, q1));
|
trail().push(insert_map(m_hoq2q, q1));
|
||||||
trail().push(insert_map(m_hopat2free_vars, p1));
|
trail().push(insert_map(m_hopat2free_vars, p1));
|
||||||
p = p1;
|
return { q1, p1 };
|
||||||
return q1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ho_matcher::is_ho_pattern(app* p) {
|
bool ho_matcher::is_ho_pattern(app* p) {
|
||||||
|
|
|
@ -386,7 +386,7 @@ namespace euf {
|
||||||
|
|
||||||
void operator()(expr* pat, expr* t, unsigned num_bound, unsigned num_vars);
|
void operator()(expr* pat, expr* t, unsigned num_bound, unsigned num_vars);
|
||||||
|
|
||||||
quantifier* compile_ho_pattern(quantifier* q, app*& p);
|
std::pair<quantifier*, app*> compile_ho_pattern(quantifier* q, app* p);
|
||||||
|
|
||||||
bool is_ho_pattern(app* p);
|
bool is_ho_pattern(app* p);
|
||||||
|
|
||||||
|
|
|
@ -98,28 +98,36 @@ namespace euf {
|
||||||
[&](ho_subst& s) {
|
[&](ho_subst& s) {
|
||||||
IF_VERBOSE(1, s.display(verbose_stream() << "on-match\n") << "\n");
|
IF_VERBOSE(1, s.display(verbose_stream() << "on-match\n") << "\n");
|
||||||
auto& b = *m_ho_binding;
|
auto& b = *m_ho_binding;
|
||||||
auto* hopat = b.m_pattern;
|
|
||||||
auto* hoq = b.m_q;
|
auto* hoq = b.m_q;
|
||||||
auto* q = m_matcher.hoq2q(hoq);
|
auto* q = m_matcher.hoq2q(hoq);
|
||||||
// shrink binding
|
// shrink binding
|
||||||
expr_ref_vector binding(m);
|
expr_ref_vector binding(m);
|
||||||
for (unsigned i = 0; i < s.size(); ++i)
|
for (unsigned i = 0; i < s.size(); ++i)
|
||||||
binding.push_back(s.get(i));
|
binding.push_back(s.get(i));
|
||||||
binding.reverse();
|
|
||||||
if (binding.size() > q->get_num_decls()) {
|
if (binding.size() > q->get_num_decls()) {
|
||||||
bool change = true;
|
bool change = true;
|
||||||
while (change) {
|
while (change) {
|
||||||
change = false;
|
change = false;
|
||||||
for (unsigned i = binding.size(); i-- > 0;) {
|
for (unsigned i = 1; i < binding.size();) {
|
||||||
var_subst sub(m, false);
|
var_subst sub(m);
|
||||||
auto r = sub(binding.get(i), binding);
|
auto r = sub(binding.get(i), binding);
|
||||||
change |= r != binding.get(i);
|
change |= r != binding.get(i);
|
||||||
|
m_rewriter(r);
|
||||||
binding[i] = r;
|
binding[i] = r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
binding.reverse();
|
||||||
|
binding.shrink(q->get_num_decls());
|
||||||
|
binding.reverse();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (unsigned i = 0; i < binding.size();) {
|
||||||
|
expr_ref r(binding.get(i), m);
|
||||||
|
m_rewriter(r);
|
||||||
|
binding[i] = r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
binding.shrink(q->get_num_decls());
|
|
||||||
binding.reverse();
|
|
||||||
|
|
||||||
IF_VERBOSE(1, verbose_stream() << binding << "\n");
|
IF_VERBOSE(1, verbose_stream() << binding << "\n");
|
||||||
apply_binding(b, q, binding);
|
apply_binding(b, q, binding);
|
||||||
|
@ -264,23 +272,36 @@ namespace euf {
|
||||||
};
|
};
|
||||||
expr* x, * y;
|
expr* x, * y;
|
||||||
if (m.is_eq(f, x, y)) {
|
if (m.is_eq(f, x, y)) {
|
||||||
enode* a = mk_enode(x);
|
expr_ref x1(x, m);
|
||||||
enode* b = mk_enode(y);
|
expr_ref y1(y, m);
|
||||||
|
m_rewriter(x1);
|
||||||
|
m_rewriter(y1);
|
||||||
|
enode* a = mk_enode(x1);
|
||||||
|
enode* b = mk_enode(y1);
|
||||||
|
if (a->get_root() == b->get_root())
|
||||||
|
return;
|
||||||
m_egraph.merge(a, b, to_ptr(push_pr_dep(pr, d)));
|
m_egraph.merge(a, b, to_ptr(push_pr_dep(pr, d)));
|
||||||
add_children(a);
|
add_children(a);
|
||||||
add_children(b);
|
add_children(b);
|
||||||
m_should_propagate = true;
|
m_should_propagate = true;
|
||||||
|
if (m_side_condition_solver)
|
||||||
|
m_side_condition_solver->add_constraint(f, pr, d);
|
||||||
}
|
}
|
||||||
else if (m.is_not(f, f)) {
|
else if (m.is_not(f, f)) {
|
||||||
enode* n = mk_enode(f);
|
enode* n = mk_enode(f);
|
||||||
|
if (m.is_false(n->get_root()->get_expr()))
|
||||||
|
return;
|
||||||
auto j = to_ptr(push_pr_dep(pr, d));
|
auto j = to_ptr(push_pr_dep(pr, d));
|
||||||
m_egraph.new_diseq(n, j);
|
m_egraph.new_diseq(n, j);
|
||||||
add_children(n);
|
add_children(n);
|
||||||
m_should_propagate = true;
|
m_should_propagate = true;
|
||||||
|
if (m_side_condition_solver)
|
||||||
|
m_side_condition_solver->add_constraint(f, pr, d);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
enode* n = mk_enode(f);
|
enode* n = mk_enode(f);
|
||||||
|
if (m.is_true(n->get_root()->get_expr()))
|
||||||
|
return;
|
||||||
m_egraph.merge(n, m_tt, to_ptr(push_pr_dep(pr, d)));
|
m_egraph.merge(n, m_tt, to_ptr(push_pr_dep(pr, d)));
|
||||||
add_children(n);
|
add_children(n);
|
||||||
if (is_forall(f)) {
|
if (is_forall(f)) {
|
||||||
|
@ -296,20 +317,24 @@ namespace euf {
|
||||||
|
|
||||||
for (unsigned i = 0; i < q->get_num_patterns(); ++i) {
|
for (unsigned i = 0; i < q->get_num_patterns(); ++i) {
|
||||||
auto p = to_app(q->get_pattern(i));
|
auto p = to_app(q->get_pattern(i));
|
||||||
auto q1 = m_matcher.compile_ho_pattern(q, p);
|
auto [q1, p1] = m_matcher.compile_ho_pattern(q, p);
|
||||||
ptr_vector<app> ground;
|
ptr_vector<app> ground;
|
||||||
mam::ground_subterms(p, ground);
|
mam::ground_subterms(p, ground);
|
||||||
|
if (p1 != p)
|
||||||
|
mam::ground_subterms(p1, ground);
|
||||||
for (expr* g : ground)
|
for (expr* g : ground)
|
||||||
mk_enode(g);
|
mk_enode(g);
|
||||||
m_mam->add_pattern(q1, p);
|
m_mam->add_pattern(q, p);
|
||||||
|
if (p != p1)
|
||||||
|
m_mam->add_pattern(q1, p1);
|
||||||
}
|
}
|
||||||
m_q2dep.insert(q, { pr, d});
|
m_q2dep.insert(q, { pr, d});
|
||||||
get_trail().push(insert_obj_map(m_q2dep, q));
|
get_trail().push(insert_obj_map(m_q2dep, q));
|
||||||
}
|
}
|
||||||
add_rule(f, pr, d);
|
add_rule(f, pr, d);
|
||||||
|
if (!is_forall(f) && !m.is_implies(f) && m_side_condition_solver)
|
||||||
|
m_side_condition_solver->add_constraint(f, pr, d);
|
||||||
}
|
}
|
||||||
if (m_side_condition_solver)
|
|
||||||
m_side_condition_solver->add_constraint(f, pr, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool completion::eval_cond(expr* f, proof_ref& pr, expr_dependency*& d) {
|
lbool completion::eval_cond(expr* f, proof_ref& pr, expr_dependency*& d) {
|
||||||
|
@ -357,6 +382,7 @@ namespace euf {
|
||||||
body.push_back(x);
|
body.push_back(x);
|
||||||
flatten_and(body);
|
flatten_and(body);
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
|
flet<bool> _propagate_with_solver(m_propagate_with_solver, true);
|
||||||
|
|
||||||
for (auto f : body) {
|
for (auto f : body) {
|
||||||
switch (eval_cond(f, pr_i, d)) {
|
switch (eval_cond(f, pr_i, d)) {
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
|
|
||||||
bool is_true(expr* f, proof_ref& pr, expr_dependency*& d) override {
|
bool is_true(expr* f, proof_ref& pr, expr_dependency*& d) override {
|
||||||
d = nullptr;
|
d = nullptr;
|
||||||
|
init_solver();
|
||||||
solver::scoped_push _sp(*m_solver);
|
solver::scoped_push _sp(*m_solver);
|
||||||
m_fmls.reset();
|
m_fmls.reset();
|
||||||
m_fmls.push_back(m.mk_not(f));
|
m_fmls.push_back(m.mk_not(f));
|
||||||
|
@ -113,6 +114,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void solve_for(vector<solution>& sol) override {
|
void solve_for(vector<solution>& sol) override {
|
||||||
|
init_solver();
|
||||||
vector<solver::solution> ss;
|
vector<solver::solution> ss;
|
||||||
for (auto [v, t, g] : sol)
|
for (auto [v, t, g] : sol)
|
||||||
ss.push_back({ v, t, g });
|
ss.push_back({ v, t, g });
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue