3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-14 19:15:41 +00:00

Add QE regression for unsound check-sat-using qe result on quantified reals (#10097)

`check-sat-using qe` was reported to return `unsat` on a satisfiable
quantified-real formula, while a subsequent `check-sat` on the same
assertion returned `sat`. This PR adds focused regression coverage for
that shape to prevent reintroduction.

- **Regression coverage for the reported formula**
  - Added `test_qe_regression_4175()` in `src/test/quant_solve.cpp`.
  - Parses and quantifier-eliminates:
    ```smt2
    (forall ((b Real)) (= (= r1 b) (= b 0)))
    ```

- **Behavioral oracle encoded in the test**
  - Verifies the QE result is satisfiable under `r1 = 0`.
  - Verifies the QE result is unsatisfiable under `r1 != 0`.
- This captures the intended semantics of the original formula and
guards against the unsound `unsat` outcome from the QE path.

- **Integration**
- Wires the new regression into `tst_quant_solve()` so it runs with
existing quantifier-solver test coverage.

Example snippet from the new test logic:

```cpp
solver.assert_expr(result);
solver.assert_expr(m.mk_eq(r1, zero));
VERIFY(l_true == solver.check());

solver.assert_expr(result);
solver.assert_expr(m.mk_not(m.mk_eq(r1, zero)));
VERIFY(l_false == solver.check());
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
Copilot 2026-07-12 18:53:15 -07:00 committed by GitHub
parent 4862a10ffd
commit 7d67dbfcfc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -168,6 +168,36 @@ static void test_quant_solver(ast_manager& m, char const* str, bool validate = t
test_quant_solver(m, vars.size(), vars.data(), fml, validate);
}
static void test_qe_regression_4175() {
ast_manager m;
reg_decl_plugins(m);
smt_params params;
arith_util a(m);
expr_ref fml = parse_fml(m, "(forall ((b Real)) (= (= r1 b) (= b 0)))");
VERIFY(fml);
expr_ref result(m);
qe::expr_quant_elim qe(m, params);
qe(m.mk_true(), fml, result);
VERIFY(result);
expr_ref r1(m.mk_const(symbol("r1"), a.mk_real()), m);
expr_ref zero(a.mk_numeral(rational(0), false), m);
{
smt::kernel solver(m, params);
solver.assert_expr(result);
solver.assert_expr(m.mk_eq(r1, zero));
VERIFY(l_true == solver.check());
}
{
smt::kernel solver(m, params);
solver.assert_expr(result);
solver.assert_expr(m.mk_not(m.mk_eq(r1, zero)));
VERIFY(l_false == solver.check());
}
}
static void test_quant_solve1() {
ast_manager m;
@ -253,6 +283,7 @@ void tst_quant_solve() {
disable_debug("heap");
test_quant_solve1();
test_qe_regression_4175();
#if 0
memory::finalize();
@ -262,5 +293,3 @@ void tst_quant_solve() {
exit(0);
#endif
}