Adjacent-swap pivot Gram-determinant product #
Swapping adjacent rows km1, k (with km1 + 1 = k) of b changes only the
leading k × k Gram determinant within 0 ≤ t ≤ k + 1. The new pivot Gram
determinant gramDet (rowSwap b km1 k) k satisfies the integer product
identity
gramDet b' k · gramDet b k = gramDet b (k+1) · gramDet b km1 + B²
where B = (scaledCoeffs b)[k][km1]. This is the fraction-free form of the
standard rational adjacent-swap update used by integer LLL.
The rational dot product is additive in its left argument.
The rational dot product is homogeneous in its left argument: a scalar factors out.
Pythagoras: if curr ⊥ prev, then the squared norm of curr + μ • prev
splits as ‖curr‖² + μ² · ‖prev‖².
For j < km1.val, the Gram-Schmidt basis row is unchanged by the swap
of rows km1, k. The norm-square product over indices < km1.val therefore
agrees on b and Matrix.rowSwap b km1 k.
Unconditional version of gramDet_eq_prod_normSq: the leading Gram
determinant casts to the rational gramSchmidtNormProduct without requiring
linear independence. The independent hypothesis in the public theorem is
not actually used by the proof.
Same as gramDet_subst_val for gramSchmidtNormProduct.
Integer fraction-free identity for the leading pivot Gram determinant
after swapping adjacent rows km1, k with km1.val + 1 = k.val:
gramDet b' k · gramDet b k = gramDet b (k+1) · gramDet b km1 + B²
where B = (scaledCoeffs b)[k][km1]. This is the algebraic heart of the
integer LLL adjacent-swap update.
Dotting the j-th Gram-Schmidt basis row with the integer-cast i-th
input row picks out the (i, j) Gram-Schmidt coefficient weighted by the
squared norm of the basis row. Holds unconditionally: when the basis row is
zero, both sides vanish (orthogonality + the if-branch in
coeffs_lower_projection).
For an adjacent row swap b' = rowSwap b km1 k with km1.val + 1 = k.val,
the dot product of the swapped k-th basis row with the original km1-th basis
row equals the squared norm of the swapped k-th basis row. Equivalently,
dot u_k prev = ||u_k||², where u_k = (basis b').row k and prev = (basis b).row km1.
The proof routes both sides through dot u_k (cast b.row km1) = dot u_k (cast b'.row k)
(the cast vectors agree because b'.row k = b.row km1 from the row swap),
expanding each side via basis_decomposition. The prefix combinations vanish on
both sides because u_k = (basis b').row k is orthogonal to every (basis b').row q
with q < k, and the relevant (basis b).row q agrees with (basis b').row q
for q < km1.
For an adjacent row swap b' = rowSwap b km1 k with km1.val + 1 = k.val,
the dot product of the swapped k-th basis row with the integer-cast i-th
input row (for i > k) decomposes as the dot product of u_k with the original
km1-th basis row times a linear combination of the original km1-th and
k-th coefficients of row i.
Concretely, with μ = c[k][km1]:
dot u_k (cast b.row i) = (dot u_k prev) * (c[i][km1] - μ * c[i][k])
This is the "Cramer-style" dot product expansion that, combined with
dot_basis_rowSwap_curr_prev_eq_normSq, lets us extract c'[i][k] from the
b'-side Cramer formula c'[i][k] * ||u_k||² = dot u_k (cast b.row i).
Conditional form of the leading Gram determinant identity. The remaining
unconditional fact is exactly the nonnegativity of leading Gram determinants:
once 0 ≤ det is available, the public Nat-valued gramDet casts back to
the signed determinant.
Mathlib-side unconditional diagonal synchronization for the public scaled-coefficient matrix. The Mathlib-free core exposes the Nat-level version and the conditional Int lift; the required nonnegativity of the Gram/Bareiss diagonal slot is supplied here.
The leading executable Gram determinants of a square upper-triangular integer matrix with strictly positive diagonal are positive.
This theorem lives in HexGramSchmidtMathlib: its proof identifies the
executable gramDet with the Leibniz determinant of the leading Gram matrix
via the composition of HexMatrixMathlib.bareiss_eq_mathlib_det and
HexMatrixMathlib.det_eq.symm.