3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-05-17 07:29:28 +00:00
Commit graph

3 commits

Author SHA1 Message Date
Lev Nachmanson
ff49d60e64 lexicographical version
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
2026-05-15 19:20:02 -07:00
Lev Nachmanson
2ba7d7ed70 lll-cube: weight C(B) by column tightness to favor tight-box rows
Replace the unweighted greedy with a weighted cube cost
  C(B) = sum_j w_j * delta_j(B) + sum_i delta_i(B)
where w_j = max(1, 2/width(j)) for columns with finite [lb, ub] and 1
elsewhere. compute_col_weights() runs once after build_matrix(); the
breakpoint pairing in reduce_pair() now carries a combined weight and
sorts/medians/evaluates with it.

Soundness is unchanged: weights only steer the choice of B; the actual
delta_col(j) = (1/2)||row_j(B)||_1 used to tighten bounds is recomputed
from the resulting B.

On the QF_LIA Bromberger CAV_2009 family this enables the rounding path
to fire for the first time: v45_problem_2__028.slack solves in 0.88s
(LLL on) vs 7.05s (LLL off), with arith-lll-cube-success = 1.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-15 14:43:41 -07:00
Lev Nachmanson
5336b2c601 Add LLL cube heuristic for integer LP (experimental, default off)
Generalize int_cube from the unit cube C = [-1/2, 1/2]^n to a
parallelepiped K = B * C where B is an n x n unimodular integer matrix
found by a monotone pairwise basis-reduction that directly minimizes
the actual cube cost

    C(B) = (1/2) * (||A * B||_1 + ||B||_1)
         = sum_r delta_row(r, B) + sum_j delta_col(j, B)

The atomic move is a single elementary column op col_j -= q * col_k
with q chosen to minimize C(B) analytically (floor/ceil of the weighted
median of breakpoints {H[r,j]/H[r,k]} and {B[i,j]/B[i,k]}).  Starting
from B = I and accepting only strict improvements makes the heuristic
*monotone-safe*: never worse than the plain int_cube.  This addresses
the regression of int_cube_hnf (branch hnf_cube), whose triangulation
can blow up the column-delta term ||B||_1.  In a 153-instance random
matrix study the HNF basis was worse than B=I by an average factor
3x-50x, while pairwise-greedy LLL was uniformly >= plain cube.

Implementation:
* src/math/lp/int_cube_lll.{h,cpp} -- the heuristic.
* The infrastructure (collect J/terms, tighten bounds, round on a
  saved x_J snapshot, lar_solver::apply_lattice_assignment) mirrors
  the earlier hnf_cube experiment; the only algorithmic change is
  swapping HNF column-reduction for the cost-minimizing pairwise
  reduction with bail-on-overflow.

New parameters:
* lp.enable_lll_cube (bool, default false) -- feature gate.
* lp.int_find_lll_cube_period (uint, default 4) -- the LLL cube is
  invoked every Nth final-check call after a plain cube failure.
  Because it is monotone-safe it runs at cube's period (4) rather
  than the throttled 16 the HNF variant used.

Statistics: arith-lll-cube-{calls,success,bail-collect,bail-build,
bail-basis,bail-tighten,bail-infeasible}.

Resource limits: rows <= 75, cols <= 150, bitsize <= 4096, max_passes
<= 8; bail above.

Validation:
* test-z3 /a: 89/89 unit tests pass.
* Smoke run on QF_LIA cut_lemmas and CAV_2009/Bromberger samples:
  no result disagreements vs. plain cube; one timeout-to-sat win on
  20180326-Bromberger/.../unbd-sage0.smt2 (-T:15).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-15 11:34:16 -07:00