mirror of
https://github.com/Z3Prover/z3
synced 2026-07-25 00:12:34 +00:00
Spacer crashed in quantifier-elimination projection on certain HORN inputs when model evaluation produced arithmetic expressions that were not plain numerals. The failure was an assertion in `spacer_qe_project.cpp` during sign/offset computation for projected literals. - **Projection robustness in Spacer arithmetic QE** - Updated numeral extraction in `src/muz/spacer/spacer_qe_project.cpp` from `is_numeral` to `is_extended_numeral` at all model-evaluation sites used by projection. - This covers evaluated arithmetic forms (e.g., normalized arithmetic expressions) that are semantically numeric but not syntactic numerals, preventing assertion failures in disequality/equality handling and bound selection. - **Regression coverage for the crashing HORN shape** - Added a focused regression in `src/test/api_datalog.cpp` that evaluates the reported Spacer/HORN input pattern through `Z3_eval_smtlib2_string`. - The test exercises the exact QE/projection path that previously triggered the assertion. ```cpp // Before VERIFY(a.is_numeral(val, r)); // After VERIFY(a.is_extended_numeral(val, r)); ``` --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
parent
d99b6e7b08
commit
4862a10ffd
2 changed files with 144 additions and 5 deletions
|
|
@ -367,7 +367,7 @@ class arith_project_util {
|
|||
cx = mk_mul(c, m_var->x());
|
||||
cxt = mk_add(cx, t);
|
||||
val = mdl(cxt);
|
||||
VERIFY(a.is_numeral(val, r));
|
||||
VERIFY(a.is_extended_numeral(val, r));
|
||||
SASSERT(r > rational::zero() || r < rational::zero());
|
||||
if (r > rational::zero()) {
|
||||
c = -c;
|
||||
|
|
@ -473,7 +473,7 @@ class arith_project_util {
|
|||
cx = mk_mul(c, m_var->x());
|
||||
cxt = mk_add(cx, t);
|
||||
val = mdl(cxt);
|
||||
VERIFY(a.is_numeral(val, r));
|
||||
VERIFY(a.is_extended_numeral(val, r));
|
||||
|
||||
if (is_eq) {
|
||||
TRACE(qe, tout << "equality term\n";);
|
||||
|
|
@ -711,7 +711,7 @@ class arith_project_util {
|
|||
cx = mk_mul(m_coeffs[max_t], m_var->x());
|
||||
cxt = mk_add(cx, m_terms.get(max_t));
|
||||
val = mdl(cxt);
|
||||
VERIFY(a.is_numeral(val, r));
|
||||
VERIFY(a.is_extended_numeral(val, r));
|
||||
|
||||
// get the offset from the smallest/largest possible value for x
|
||||
// literal smallest/largest val of x
|
||||
|
|
@ -771,13 +771,13 @@ class arith_project_util {
|
|||
// evaluate x in mdl
|
||||
rational r_x;
|
||||
val = mdl(m_var->x());
|
||||
VERIFY(a.is_numeral(val, r_x));
|
||||
VERIFY(a.is_extended_numeral(val, r_x));
|
||||
|
||||
for (unsigned i = 0; i < m_terms.size(); ++i) {
|
||||
rational const &ac = m_coeffs[i];
|
||||
if (!m_eq[i] && ac.is_pos() == do_pos) {
|
||||
val = mdl(m_terms.get(i));
|
||||
VERIFY(a.is_numeral(val, r));
|
||||
VERIFY(a.is_extended_numeral(val, r));
|
||||
r /= abs(ac);
|
||||
// skip the literal if false in the model
|
||||
if (do_pos) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue