3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-15 03:25:43 +00:00
z3/src
Lev Nachmanson 6a62a53181
qsat: decide quantifier-free goals so qe2 returns sat instead of unknown (fixes iss-7027/small-30) (#9970)
## Summary

Fixes the `iss-7027/small-30` snapshot regression (`Z3Prover/bench`
discussion #2705) **at its root**, instead of working around it by
retuning the LP heuristics.

- **Benchmark:** `inputs/issues/iss-7027/small-30.smt2` —
`(check-sat-using qe2)` over a single `(distinct ...)` of 33 mixed
Int/Real terms.
- The recorded oracle was `unknown`; current `master` produces
`timeout`.

## Root cause

`unknown`/`timeout` are both wrong here: the formula is a `distinct`
over 33 terms (free Int/Real constants plus the literals `0`/`1`), which
is **trivially `sat`** — there are infinitely many distinct reals.

The real bug is in the `qsat` tactic that backs `qe2`. Running
quantifier elimination on a **quantifier-free** formula has nothing to
eliminate, so `qsat` left an undecided residual goal and
`check-sat-using` reported `unknown`. This reproduces on any ground
formula with free variables, e.g.:

```
(declare-fun a () Int)(assert (> a 0))(check-sat-using qe2)   ; -> unknown (should be sat)
```

For `small-30` the QE alternation additionally drove `theory_lra`
integer branch-and-bound down a non-terminating path, surfacing as a
`timeout` under the capture budget (the symptom the `random_hammers`
schedule change happened to expose).

## Fix

Under `check-sat` semantics, top-level free variables are implicitly
existentially quantified. So when the `qsat` input has no quantifiers,
decide satisfiability directly (route through the existing `qsat_sat`
path) instead of producing a residual goal. `qe2`/`qe` now return
`sat`/`unsat` for ground formulas.

QE of genuinely-quantified formulas is unchanged: `apply qe2` on a
quantified goal produces the same projected formula as before (verified
identical to `master`). Only the degenerate quantifier-free case is
affected.

This supersedes the previous approach in this PR (reverting the
`lp.random_hammers` default). That default is left **unchanged**
(`true`), preserving #9958's aggregate QF_LIA benefit. `small-30` now
returns `sat` in ~0.01s regardless of the heuristic schedule, because
the QE machinery no longer runs on this ground instance.

Two changes:
- `src/qe/qsat.cpp`: short-circuit quantifier-free input to the
satisfiability decision path.
- `Z3Prover/bench` `inputs/issues/iss-7027/small-30.expected.out`:
oracle updated `unknown` -> `sat` (to be committed alongside this fix).

## Validation

```
$ z3 small-30.smt2
sat            # ~0.01s

$ echo '(declare-fun a () Int)(assert (> a 0))(check-sat-using qe2)' | z3 -in
sat
$ echo '(declare-fun a () Int)(assert (and (> a 0)(< a 0)))(check-sat-using qe2)' | z3 -in
unsat
```

Full unit-test suite (`test-z3 /a`) passes (92/92). Quantified `qe2`
round-trips (`apply qe2`) match `master` byte-for-byte.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 10:38:12 -06:00
..
ackermannization block ackermann over nested selects 2026-06-19 10:41:56 -07:00
api Fix clang warnings about casting away const. (#9933) 2026-06-23 19:57:46 -06:00
ast Derive with ranges (#9965) 2026-06-26 08:44:13 -06:00
cmd_context Use "override" keyword where needed. (#9892) 2026-06-18 13:36:14 -06:00
math lp: gate Gomory-with-dio on genuine dio failures; separate config from runtime state (#9958) 2026-06-25 14:21:44 -07:00
model Term enumeration (#9908) 2026-06-20 18:14:44 -06:00
muz Add rlimit support in fixedpoint parameters (#9798) 2026-06-10 15:13:05 -07:00
nlsat fix build warnings 2026-06-22 18:20:23 -07:00
opt Fixes necessary to compile z3 included in clang-tidy via FetchContents. (#9768) 2026-06-08 19:44:01 -07:00
params Parallel tactic (#9824) (#9825) 2026-06-26 10:36:15 -06:00
parsers Fix off-by-one column after comment lines in SMT2 scanner (#9808) 2026-06-10 06:49:31 -07:00
qe qsat: decide quantifier-free goals so qe2 returns sat instead of unknown (fixes iss-7027/small-30) (#9970) 2026-06-26 10:38:12 -06:00
sat Parallel tactic (#9824) (#9825) 2026-06-26 10:36:15 -06:00
shell Fixes necessary to compile z3 included in clang-tidy via FetchContents. (#9768) 2026-06-08 19:44:01 -07:00
smt Parallel tactic (#9824) (#9825) 2026-06-26 10:36:15 -06:00
solver Parallel tactic (#9824) (#9825) 2026-06-26 10:36:15 -06:00
tactic Parallel tactic (#9824) (#9825) 2026-06-26 10:36:15 -06:00
test Derive with ranges (#9965) 2026-06-26 08:44:13 -06:00
util Parallel tactic (#9824) (#9825) 2026-06-26 10:36:15 -06:00
CMakeLists.txt git bindings v1.0 2026-02-18 21:02:25 -08:00