3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-27 09:22:41 +00:00
Commit graph

90 commits

Author SHA1 Message Date
Lev Nachmanson
fdc32d0e60
Fix inconsistent optimization result with unvalidated LP bound (#10028) (#10040)
Fixes #10028.

## Problem

Minimizing an integer variable over a problem containing a large
`distinct` constraint returned an **inconsistent** result: the reported
optimum did not match the returned model, and it was not the true
optimum.

Reproducer from the issue (a Golomb-ruler problem, true optimum = 55):

```python
import z3
n, U = 10, 500
x = [z3.Int(f"x{i}") for i in range(n)]
o = z3.Optimize()
for xi in x: o.add(xi >= 0, xi <= U)
o.add(x[0] == 0)
for i in range(n - 1): o.add(x[i] < x[i + 1])
o.add(z3.Distinct([x[j] - x[i] for i in range(n) for j in range(i + 1, n)]))
h = o.minimize(x[n - 1])
print(o.check(), o.lower(h), o.upper(h), o.model()[x[n - 1]])
# sat 20 20 500   <-- objective 20, but model has x9 = 500 (and 20 is unsat)
```

## Root cause

A `distinct` with more than 32 arguments is encoded with a fresh
uninterpreted sort and function (`smt_internalizer.cpp`), so the
objective variable becomes a *shared symbol* whose feasible values
depend on EUF as well as arithmetic. The arithmetic relaxation therefore
only produces a **hint** for the optimum, which may over-estimate it and
be unachievable.

Two combined defects:

- `opt_solver::maximize_objective` committed the hint into
`m_objective_values` **before** validating it with `check_bound`, and
never rolled it back when validation failed. `update_objective` only
ever *raises* the stored value, so the real (achievable) model value was
discarded.
- `optsmt::geometric_lex` **ignored** the boolean return value and
asserted the blocker derived from the unachievable hint, so the very
next `check_sat` was UNSAT and the search terminated prematurely,
reporting the bogus bound together with a non-matching model.

## Fix

- `opt_solver.cpp`: do not commit the hint before it is validated. On
validation failure, `update_objective` now records the actual achievable
model value. The no-model early-return keeps its previous behavior.
- `optsmt.cpp`: `geometric_lex` now honors the validation result. When
the hint could not be validated, it discards the poisoned blocker and
tightens from the real model value, so the search keeps converging
toward the true optimum. When the hint is valid, the condition reduces
to the original expression and behavior is unchanged.

After the fix the same reproducer produces consistent,
monotonically-improving bounds (325 → 85 → … → 58 → … → 55), and the
reported objective always matches the returned model.

## Testing

Exact-optimum, fast-terminating checks (all correct): EUF-forced minimum
(= 5), `distinct(x, 0..32)` minimize (= 33), Golomb n=8 (= 34), plus
basic min/max, real objective, box, lex, pareto, and weighted
soft/maxsat.

Regression suites, rebuilt in **both Release and Debug**:

| Suite | Release | Debug |
|-------|---------|-------|
| `test-z3 /a` | 92 passed, 0 failed | 92 passed, 0 failed |
| z3test `regressions/smt2` (908 files, `model_validate=true`) | 0
failures | 0 failures |

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 17:28:42 -07:00
Lev Nachmanson
8cc75d444e fix box mode: reset bounds before each objective
update_lower_lex updates m_lower for subsequent objectives with saved
values from the current model. Reset m_lower[i] and m_upper[i] to
their initial values before optimizing each objective so earlier
objectives do not contaminate later ones.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-19 17:07:21 -10:00
Lev Nachmanson
1c70b9e6ee fix box mode: isolate m_lower/m_upper between objectives
geometric_lex's update_lower_lex updates m_lower for all subsequent
objectives with saved values from the current model. In box mode this
contaminates later objectives' starting bounds, causing platform-dependent
results. Save and restore m_lower/m_upper across iterations so each
objective starts from a clean state.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-19 17:07:21 -10:00
Lev Nachmanson
acd2e9475d fix #9030: box mode objectives are now optimized independently
In box mode (opt.priority=box), each objective should be optimized
independently. Previously, box() called geometric_opt() which optimizes
all objectives together using a shared disjunction of bounds. This caused
adding/removing an objective to change the optimal values of other
objectives.

Fix: Rewrite box() to optimize each objective in its own push/pop scope
using geometric_lex, ensuring complete isolation between objectives.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-19 17:07:21 -10:00
Lev Nachmanson
5df80705aa Fix inconsistent optimization with scaled objectives (#8998)
When the LP optimizer returns the same blocker expression in successive
iterations of geometric_lex (e.g., due to nonlinear constraints like
mod/to_int preventing the LP from exploring the full feasible region),
the loop now falls back to using the model-based lower bound to push
harder instead of breaking immediately.

This fixes the case where minimize(3*a) incorrectly returned -162
while minimize(a) correctly returned -infinity with the same constraints.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-15 11:12:21 -10:00
LeeYoungJoon
0a93ff515d
Centralize and document TRACE tags using X-macros (#7657)
* Introduce X-macro-based trace tag definition
- Created trace_tags.def to centralize TRACE tag definitions
- Each tag includes a symbolic name and description
- Set up enum class TraceTag for type-safe usage in TRACE macros

* Add script to generate Markdown documentation from trace_tags.def
- Python script parses trace_tags.def and outputs trace_tags.md

* Refactor TRACE_NEW to prepend TraceTag and pass enum to is_trace_enabled

* trace: improve trace tag handling system with hierarchical tagging

- Introduce hierarchical tag-class structure: enabling a tag class activates all child tags
- Unify TRACE, STRACE, SCTRACE, and CTRACE under enum TraceTag
- Implement initial version of trace_tag.def using X(tag, tag_class, description)
  (class names and descriptions to be refined in a future update)

* trace: replace all string-based TRACE tags with enum TraceTag
- Migrated all TRACE, STRACE, SCTRACE, and CTRACE macros to use enum TraceTag values instead of raw string literals

* trace : add cstring header

* trace : Add Markdown documentation generation from trace_tags.def via mk_api_doc.py

* trace : rename macro parameter 'class' to 'tag_class' and remove Unicode comment in trace_tags.h.

* trace : Add TODO comment for future implementation of tag_class activation

* trace : Disable code related to tag_class until implementation is ready (#7663).
2025-05-28 14:31:25 +01:00
Nikolaj Bjorner
ea1360ee46 fix #7578
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2025-03-09 17:01:42 -07:00
Nikolaj Bjorner
c002c77e5a fix #7569
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2025-03-07 11:53:01 -08:00
Nikolaj Bjorner
17d47ca8c7 fix #7493 2025-02-02 15:00:31 -08:00
Nikolaj Bjorner
7baa4f88b0 build failure 2022-01-06 15:17:57 -08:00
Nikolaj Bjorner
6a3fe514f0 build
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2022-01-06 14:07:54 -08:00
Nikolaj Bjorner
dadda86bdc #5751 2022-01-06 11:43:17 -08:00
Nikolaj Bjorner
b6f7deacf4 fix #5663 2021-11-12 11:36:42 -08:00
Nikolaj Bjorner
0490056e7a na
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2021-05-17 19:19:28 -07:00
Nikolaj Bjorner
8384f38eb5 fix #5254 2021-05-17 15:42:01 -07:00
Nikolaj Bjorner
a19e469cc2 fix #5212 2021-04-24 13:27:41 -07:00
Nikolaj Bjorner
4a6083836a call it data instead of c_ptr for approaching C++11 std::vector convention. 2021-04-13 18:17:35 -07:00
Nikolaj Bjorner
a32fabf5ee fix #4403
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-06-05 13:51:31 -07:00
Nikolaj Bjorner
426e4cc75c fix #3557
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-04-03 16:37:59 -07:00
Nikolaj Bjorner
e2a247a64a fix #3601
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-03-31 13:48:44 -07:00
Nikolaj Bjorner
0b10cb3312 fix #3528
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-03-30 11:00:02 -07:00
Nikolaj Bjorner
868a6b3594 fix #3521
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-03-26 09:44:00 -07:00
Nikolaj Bjorner
f92050c7e5 fix #3515
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-03-25 13:21:02 -07:00
Nikolaj Bjorner
044d6316ca fix #3417
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-03-19 09:39:21 -07:00
Nikolaj Bjorner
82273da630 fix #2945
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-02-09 15:43:21 -08:00
Nikolaj Bjorner
63840806d8 fix #2546, retrieve model in optsmt lex before iterating
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2019-09-10 11:19:59 +02:00
Nikolaj Bjorner
35fa24a82a initialize best model
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2019-08-28 12:31:13 -03:00
Nikolaj Bjorner
20dc59e02d fix #2523
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2019-08-28 12:28:33 -03:00
Nikolaj Bjorner
75b1e8fe27 add tracing for 2157
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2019-03-12 20:12:17 -07:00
Nikolaj Bjorner
7aa8b4ac2a restrict idiv-bound checks to bounded terms
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2019-03-03 19:11:22 -08:00
Nikolaj Bjorner
c45ab6efed add setting to dump intermediary models #2087
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2019-01-18 15:12:08 -08:00
Nikolaj Bjorner
0b84c60886 fix another bug uncovered by Dunlop, prepare grounds for equality solving within NNFs
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2019-01-14 01:25:25 -08:00
Nikolaj Bjorner
335d672bf1 fix #1675, regression in core processing in maxres
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2018-06-19 23:23:19 -07:00
Nikolaj Bjorner
a81a8de975 remove lns
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2018-03-25 19:54:11 -07:00
Bruce Mitchener
76eb7b9ede Use nullptr. 2018-02-12 14:05:55 +07:00
Nikolaj Bjorner
8357210d3c fix lack of warning/error for unbounded objectives in context of quantifiers #1382
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2017-12-01 01:07:41 -08:00
Nikolaj Bjorner
2b82fd5d0c updated include directives
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2017-08-01 10:51:47 -07:00
Nikolaj Bjorner
b19f94ae5b make include paths uniformly use path relative to src. #534
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2017-07-31 13:24:11 -07:00
Nikolaj Bjorner
ec565ae7a0 fixes to #596 and #592: use exponential step increments on integer problems, align int.to.str with canonizer and disequality checker
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2016-05-17 01:00:42 -07:00
Nikolaj Bjorner
5994c5a948 fix partial model tracking over cancellation/exceptions, reported by August Shi. Fix regression test for fp-to-real, reset the pre-processor in inc_sat_solver on exceptions
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2016-03-07 16:42:29 -08:00
Nikolaj Bjorner
32b6b2da44 moving to resource managed cancellation
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2015-12-11 13:13:11 -08:00
Nikolaj Bjorner
c58e640563 extract labels for optimal model. Fix to #325
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2015-11-18 14:53:08 -08:00
Nikolaj Bjorner
d06207f072 remove ite terms from objectives to synchronize values in tableau with objective value. Fixes part of (three repros) from issue #120
Signed-off-by: Nikolaj Bjorner <nbjorner@hotmail.com>
2015-06-02 10:38:22 -07:00
Nikolaj Bjorner
a0f0b53686 fixes to #52, #53
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2015-04-28 14:48:59 -07:00
Nikolaj Bjorner
f8d04118d8 switch models for multiple box objectives. Feature request at codeplex issue 194, George Karpenov. Usage model is same as Pareto fronts you call check-sat multiple times until retrieving unsat
Signed-off-by: Nikolaj Bjorner <nbjorner@hotmail.com>
2015-04-01 16:21:56 -07:00
Nikolaj Bjorner
e24db56650 integrating new integer primal loop
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2015-01-20 16:38:45 -08:00
Nikolaj Bjorner
f4dfb9ac82 Merge branch 'opt' of https://git01.codeplex.com/z3 into opt 2014-12-09 20:57:34 +01:00
Nikolaj Bjorner
08cb8b8de8 address divergence in the case of shared theory symbols. Codeplex issue 147, thanks to George Karpenkov
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2014-12-09 16:04:25 +01:00
Nikolaj Bjorner
e9baaa0900 rename 'or' to 'fml' toe mae gcc happy, reported by Geroge Karpenkov
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2014-11-25 10:23:41 -08:00
Nikolaj Bjorner
630a3d6ea8 integrate bounds from original model
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2014-10-15 15:11:31 -07:00