3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 04:03:39 +00:00

add handling of quantifiers #5612

This commit is contained in:
Nikolaj Bjorner 2021-10-20 12:27:56 -04:00
parent 839a0852fe
commit 13da6a02a6
4 changed files with 27 additions and 19 deletions

View file

@ -1192,7 +1192,6 @@ namespace smt {
bool more_than_k_unassigned_literals(clause * cls, unsigned k); bool more_than_k_unassigned_literals(clause * cls, unsigned k);
void internalize_assertions();
void asserted_inconsistent(); void asserted_inconsistent();
@ -1609,6 +1608,8 @@ namespace smt {
void assert_expr(expr * e, proof * pr); void assert_expr(expr * e, proof * pr);
void internalize_assertions();
void push(); void push();
void pop(unsigned num_scopes); void pop(unsigned num_scopes);

View file

@ -50,7 +50,7 @@ namespace smt {
n->m_lbl_hash = -1; n->m_lbl_hash = -1;
n->m_proof_is_logged = false; n->m_proof_is_logged = false;
unsigned num_args = n->get_num_args(); unsigned num_args = n->get_num_args();
for (unsigned i = 0; i < num_args; i++) { for (unsigned i = 0; i < num_args; i++) {
enode * arg = app2enode[owner->get_arg(i)->get_id()]; enode * arg = app2enode[owner->get_arg(i)->get_id()];
n->m_args[i] = arg; n->m_args[i] = arg;
SASSERT(n->get_arg(i) == arg); SASSERT(n->get_arg(i) == arg);

View file

@ -297,7 +297,7 @@ namespace smt {
TRACE("datatype", tout << "internalizing term:\n" << mk_pp(term, m) << "\n";); TRACE("datatype", tout << "internalizing term:\n" << mk_pp(term, m) << "\n";);
unsigned num_args = term->get_num_args(); unsigned num_args = term->get_num_args();
for (unsigned i = 0; i < num_args; i++) for (unsigned i = 0; i < num_args; i++)
ctx.internalize(term->get_arg(i), false); ctx.internalize(term->get_arg(i), has_quantifiers(term));
// the internalization of the arguments may trigger the internalization of term. // the internalization of the arguments may trigger the internalization of term.
if (ctx.e_internalized(term)) if (ctx.e_internalized(term))
return true; return true;

View file

@ -246,18 +246,22 @@ namespace smt {
literal theory_recfun::mk_eq_lit(expr* l, expr* r) { literal theory_recfun::mk_eq_lit(expr* l, expr* r) {
literal lit; literal lit;
if (m.is_true(r) || m.is_false(r)) { if (has_quantifiers(l) || has_quantifiers(r)) {
std::swap(l, r); expr_ref eq1(m.mk_eq(l, r), m);
} expr_ref fn(m.mk_fresh_const("rec-eq", m.mk_bool_sort()), m);
if (m.is_true(l)) { expr_ref eq(m.mk_eq(fn, eq1), m);
lit = mk_literal(r); ctx.assert_expr(eq);
} ctx.internalize_assertions();
else if (m.is_false(l)) { lit = mk_literal(fn);
lit = ~mk_literal(r);
}
else {
lit = mk_eq(l, r, false);
} }
else if (m.is_true(r) || m.is_false(r))
std::swap(l, r);
else if (m.is_true(l))
lit = mk_literal(r);
else if (m.is_false(l))
lit = ~mk_literal(r);
else
lit = mk_eq(l, r, false);
ctx.mark_as_relevant(lit); ctx.mark_as_relevant(lit);
return lit; return lit;
} }
@ -282,14 +286,12 @@ namespace smt {
auto & vars = e.m_def->get_vars(); auto & vars = e.m_def->get_vars();
expr_ref lhs(e.m_lhs, m); expr_ref lhs(e.m_lhs, m);
unsigned depth = get_depth(e.m_lhs); unsigned depth = get_depth(e.m_lhs);
expr_ref rhs(apply_args(depth, vars, e.m_args, e.m_def->get_rhs()), m); expr_ref rhs(apply_args(depth, vars, e.m_args, e.m_def->get_rhs()), m);
literal lit = mk_eq_lit(lhs, rhs); literal lit = mk_eq_lit(lhs, rhs);
std::function<literal(void)> fn = [&]() { return lit; }; std::function<literal(void)> fn = [&]() { return lit; };
scoped_trace_stream _tr(*this, fn); scoped_trace_stream _tr(*this, fn);
ctx.mk_th_axiom(get_id(), 1, &lit); ctx.mk_th_axiom(get_id(), 1, &lit);
TRACEFN("macro expansion yields " << pp_lit(ctx, lit)); TRACEFN("macro expansion yields " << pp_lit(ctx, lit));
if (has_quantifiers(rhs))
throw default_exception("quantified formulas in recursive functions are not supported");
} }
/** /**
@ -377,6 +379,13 @@ namespace smt {
unsigned depth = get_depth(e.m_pred); unsigned depth = get_depth(e.m_pred);
expr_ref lhs(u().mk_fun_defined(d, args), m); expr_ref lhs(u().mk_fun_defined(d, args), m);
expr_ref rhs = apply_args(depth, vars, args, e.m_cdef->get_rhs()); expr_ref rhs = apply_args(depth, vars, args, e.m_cdef->get_rhs());
if (has_quantifiers(rhs)) {
expr_ref fn(m.mk_fresh_const("rec-eq", m.mk_bool_sort()), m);
expr_ref eq(m.mk_eq(fn, rhs), m);
ctx.assert_expr(eq);
ctx.internalize_assertions();
rhs = fn;
}
literal_vector clause; literal_vector clause;
for (auto & g : e.m_cdef->get_guards()) { for (auto & g : e.m_cdef->get_guards()) {
expr_ref guard = apply_args(depth, vars, args, g); expr_ref guard = apply_args(depth, vars, args, g);
@ -394,8 +403,6 @@ namespace smt {
std::function<literal_vector(void)> fn = [&]() { return clause; }; std::function<literal_vector(void)> fn = [&]() { return clause; };
scoped_trace_stream _tr(*this, fn); scoped_trace_stream _tr(*this, fn);
ctx.mk_th_axiom(get_id(), clause); ctx.mk_th_axiom(get_id(), clause);
if (has_quantifiers(rhs))
throw default_exception("quantified formulas in recursive functions are not supported");
} }
final_check_status theory_recfun::final_check_eh() { final_check_status theory_recfun::final_check_eh() {