3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-02-18 14:44:21 +00:00

preserve the initial state of the solver with push/pop for multiple objectives (#8264)

* preserve the initial state of the solver with push/pop for multiple objectives

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

* Fix memory corruption in Z3_polynomial_subresultants

The API function had a memory corruption bug where allocating the result
vector while the default_expr2polynomial converter was still in scope
could corrupt the converter's internal expr2var mapping.

Fixed by restructuring the code to:
1. Complete all polynomial computation in a scoped block
2. Store results in a temporary expr_ref_vector
3. Let the converter go out of scope
4. Then allocate and populate the result vector

Also improved the test to:
- Use randomized testing with 20 iterations
- Test both cases: variable in polynomials and variable not in polynomials
- Use proper reference counting (inc_ref before dec_ref)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Lev Nachmanson 2026-01-23 08:41:03 -10:00 committed by GitHub
parent 2a5bfb818b
commit c0583b828d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 107 additions and 40 deletions

View file

@ -202,8 +202,29 @@ namespace opt {
bool opt_solver::maximize_objectives1(expr_ref_vector& blockers) {
expr_ref blocker(m);
for (unsigned i = 0; i < m_objective_vars.size(); ++i) {
if (!maximize_objective(i, blocker))
// Push context to isolate each objective's optimization.
// This prevents bounds created during one objective's optimization
// from affecting subsequent objectives (fixes issue #7677).
m_context.push();
if (!maximize_objective(i, blocker)) {
m_context.pop(1);
return false;
}
// Save results before popping
inf_eps val = m_objective_values[i];
model_ref mdl;
if (m_models[i])
mdl = m_models[i];
m_context.pop(1);
// Restore the computed values after pop
m_objective_values[i] = val;
if (mdl)
m_models.set(i, mdl.get());
blockers.push_back(blocker);
}
return true;