mirror of
https://github.com/Z3Prover/z3
synced 2026-07-15 03:25:43 +00:00
Fix assertion violation in bv2int_translator with smt.bv.solver=2 (#10109)
`ASSERTION VIOLATION` at `bv2int_translator.h:72` when using
`smt.bv.solver=2` with formulas containing `abs` (or other arith
expressions that rewrite to ITE with arith predicates).
**Root cause**
`ensure_translated` skips adding sub-expressions of boolean non-BV nodes
to the `todo` list — correct, since the base theory owns them in plugin
mode. However, `translate_expr`'s early-return only covered
`basic_family_id` booleans, not non-basic ones (e.g.,
`arith_family_id`).
When `(abs f)` is rewritten by the arith rewriter to `(ite (>= f 0) f (-
f))`, the predicate `(>= f 0)` ends up in `todo` (as a child of the
ITE), but its own children (e.g., the integer literal `0`) are not
added. `translate_expr` then calls `translated(0)` on an unmapped
expression, firing `SASSERT(r)`.
Reproducer:
```smt2
(declare-const f Int)
(assert (= 0 (mod 0 (bv2nat ((_ int_to_bv 1) (abs f))))))
(check-sat)
; z3 test.smt2 smt.bv.solver=2 → ASSERTION VIOLATION (before fix)
```
**Fix**
Extend the early-return in `translate_expr` to match
`ensure_translated`'s skip condition — all boolean non-BV expressions in
plugin mode map to themselves:
```cpp
// before
if (m_is_plugin && ap->get_family_id() == basic_family_id && m.is_bool(ap)) {
// after
if (m_is_plugin && m.is_bool(ap) && ap->get_family_id() != bv.get_family_id()) {
```
BV boolean predicates (`bvule`, etc.) are unaffected — they still route
through `translate_bv`.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
parent
965942be79
commit
98e1f5ca2d
1 changed files with 1 additions and 1 deletions
|
|
@ -90,7 +90,7 @@ void bv2int_translator::translate_expr(expr* e) {
|
||||||
translate_var(to_var(e));
|
translate_var(to_var(e));
|
||||||
else {
|
else {
|
||||||
app* ap = to_app(e);
|
app* ap = to_app(e);
|
||||||
if (m_is_plugin && ap->get_family_id() == basic_family_id && m.is_bool(ap)) {
|
if (m_is_plugin && m.is_bool(ap) && ap->get_family_id() != bv.get_family_id()) {
|
||||||
set_translated(e, e);
|
set_translated(e, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue