mirror of
https://github.com/Z3Prover/z3
synced 2026-07-27 09:22:41 +00:00
opt: keep infinitesimal LP optimum instead of falling back to model value
When an objective's optimum is an open (strict) bound, the arithmetic
relaxation returns a value carrying a non-zero infinitesimal (e.g.
minimizing a real x subject to x > 0, whose infimum is the unattained 0,
reported as "epsilon"). opt_solver::maximize_objective validates such a
hint with check_bound(), which asserts the objective is >= val via mk_ge
and searches for a model reaching it. mk_ge cannot faithfully encode the
infinitesimal (it drops a negative infinitesimal and turns a positive one
into a strict bound), so this validation always fails spuriously for an
open optimum. Since #10028 (fdc32d0e6) stopped committing the hint before
validation, this false negative now discards the true infinitesimal
optimum and reports an attainable - strictly worse - model value instead
(x = 1 rather than epsilon).
Treat a hint with a non-zero infinitesimal as valid in check_bound: for
such open bounds the relaxation value is exact. Hints without an
infinitesimal (such as the integer objective of #10028) are still
validated normally, so that fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
557a0cadab
commit
1d936e2384
1 changed files with 16 additions and 0 deletions
|
|
@ -358,9 +358,25 @@ namespace opt {
|
|||
|
||||
//
|
||||
// check that "val" obtained from optimization hint is a valid bound.
|
||||
//
|
||||
// A hint with a non-zero infinitesimal denotes an *open* (strict)
|
||||
// optimum: the objective approaches "val" but no concrete model attains
|
||||
// it (e.g. minimizing a real x subject to x > 0, whose infimum is the
|
||||
// unattained 0, reported as "epsilon"). check_bound validates a hint by
|
||||
// asserting the objective is >= val (mk_ge) and searching for a model
|
||||
// that reaches it, but mk_ge cannot faithfully encode the infinitesimal
|
||||
// (a negative infinitesimal is dropped, a positive one becomes a strict
|
||||
// bound), so this search always fails spuriously for an open optimum.
|
||||
// In that case the arithmetic relaxation value is exact, so accept the
|
||||
// hint rather than discarding the true optimum and falling back to an
|
||||
// attainable - and therefore strictly worse - model value (issue #5314).
|
||||
// Hints without an infinitesimal (such as the integer objective of
|
||||
// #10028) are still validated normally, preserving that fix.
|
||||
//
|
||||
auto check_bound = [&]() {
|
||||
SASSERT(has_shared);
|
||||
if (!val.get_infinitesimal().is_zero())
|
||||
return true;
|
||||
return bound_value(i, val) && l_true == m_context.check(0, nullptr);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue