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>
Same as test_bnh_optimize but constructs f1 and f2 with reversed
parameter order in mk_add, mk_mul, mk_sub calls. Exposes optimizer
sensitivity to expression structure.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add ENSURE(result == Z3_L_TRUE) for each BNH optimization call and
ENSURE(num_sat == 7) at the end so CI catches regressions.
- Remove test_bnh_optimize() from tst_api() to avoid duplicate
execution under /a; keep standalone tst_bnh_opt() entry point.
- Fix Test 2 comment: it tests same-size backup, not backup-longer.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Relax restore_x() to handle backup/current size mismatches: when
backup is shorter (new columns added), call
move_non_basic_columns_to_bounds() to find a feasible solution.
- Fix 100x performance regression in nonlinear optimization: save LP
optimum before check_nla and return it as bound regardless of NLA
result, so opt_solver::check_bound() can validate via full re-solve
with accumulated NLA lemmas.
- Refactor theory_lra::maximize() into three helpers: max_with_lp(),
max_with_nl(), and max_result().
- Add mk_gt(theory_var, impq const&) overload for building blockers
from saved LP optimum values.
- Add BNH multi-objective optimization test (7/7 sat in <1s vs 1/7
in 30s before fix).
- Add restore_x test for backup size mismatch handling.
Fixes#8890
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>