mirror of
https://github.com/Z3Prover/z3
synced 2026-06-11 03:15:36 +00:00
Two fixes for mbp_dt_tg::apply() when encountering an accessor whose argument has a different constructor in the model: 1. Don't call rm_accessor (which would assert a contradictory recognizer, making the formula false). This prevents the original bug where QEL returned 'false' for satisfiable formulas. 2. Branch on the model-assigned constructor for the accessor's argument. The correct output should include the literal introduced in (2). However, this fix does not produce it. Spacer is sound with this over-approximation, as long as the counter example does not depend on value of mismatched accessors (e.g. (tl nil)). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
a0a3047e36
commit
922f49e187
4 changed files with 270 additions and 0 deletions
|
|
@ -163,6 +163,24 @@ struct mbp_dt_tg::impl {
|
|||
if (is_app(term) &&
|
||||
m_dt_util.is_accessor(to_app(term)->get_decl()) &&
|
||||
has_var(to_app(term)->get_arg(0))) {
|
||||
// Only apply rm_accessor if the model confirms the argument
|
||||
// has the constructor that this accessor belongs to.
|
||||
// Otherwise we introduce a contradictory is-cons literal.
|
||||
func_decl *cons =
|
||||
m_dt_util.get_accessor_constructor(to_app(term)->get_decl());
|
||||
func_decl *rec = m_dt_util.get_constructor_recognizer(cons);
|
||||
expr_ref is_rec(m.mk_app(rec, to_app(term)->get_arg(0)), m);
|
||||
if (!m_mdl.is_true(is_rec)) {
|
||||
// Ground the argument so the accessor term becomes
|
||||
// constructively ground. This preserves any enclosing
|
||||
// literal (e.g., (not (is-nil (tl nil)))) as a guard in
|
||||
// the output, preventing an over-approximation.
|
||||
expr_ref is(m.mk_not(is_rec), m);
|
||||
m_tg.add_lit(is);
|
||||
mark_seen(term);
|
||||
progress = true;
|
||||
continue;
|
||||
}
|
||||
mark_seen(term);
|
||||
progress = true;
|
||||
rm_accessor(term);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue