No-pivot Bareiss loop invariant for hex-matrix-mathlib.
This module proves the recursive bordered-minor invariant of the no-pivot
Bareiss recurrence: after k regular Bareiss steps, the trailing entries of
the working matrix agree with the corresponding bordered-minor determinants of
the source matrix, and the previous pivot agrees with the determinant of the
leading prefix of size k. As an immediate corollary, when all leading-prefix
determinants are nonzero (NonzeroBareissPivots), the loop never takes the
singular branch.
The invariant proof composes the bordered-minor stepMatrix update lemma
(Hex.Matrix.stepMatrix_borderedMinor_update) with the bordered-minor
specialization of Desnanot-Jacobi (desnanot_jacobi_borderedMinor in the
parent module) and the exact-division equation
(bareissExactDiv_borderedMinor_of_mul_eq).
The k-bordered minor of M at the corner row/column ⟨k, hk⟩ is exactly
the (k + 1)-leading prefix of M. This identifies the trailing-corner entry
under the no-pivot Bareiss invariant with a leading-prefix determinant.
Hypothesis used by the no-pivot Bareiss soundness proof: every leading
prefix determinant up to size n is nonzero.
Equations
- HexMatrixMathlib.NonzeroBareissPivots M = ∀ (k : Fin n), (M.principalSubmatrix (↑k + 1) ⋯).det ≠ 0
Instances For
Bordered-minor invariant of the no-pivot Bareiss recurrence:
singularStepisnone(no pivot has been zero yet);- the previous pivot equals the determinant of the leading prefix of size
state.step(which is1forstate.step = 0); - the previous pivot is nonzero (so the next step's exact division is valid);
- every trailing entry
(i, j)withstate.step ≤ i.valandstate.step ≤ j.valagrees with the determinant of thestate.step-bordered minor with trailing rowiand columnj.
The implication on diagonal entries (state.matrix[k][k] agrees with the
leading-prefix determinant of size k + 1) follows from trailing_eq taken
at i = j = ⟨k, _⟩ together with borderedMinor_corner_eq_principalSubmatrix.
Instances For
The initial Bareiss no-pivot state satisfies the bordered-minor invariant:
the matrix is the source itself, and the previous-pivot convention is
det (principalSubmatrix _ 0 _) = 1.
Public regular no-swap step surface for the row-pivoted Bareiss proof. When the current diagonal pivot is already nonzero, the row-pivoted loop takes the same regular step as the no-pivot loop, so the bordered-minor invariant is preserved by the existing no-pivot step proof.
In the pivot-search failure branch, the current pivot column is zero at and below the current step.
In the pivot-search failure branch, the bordered-minor invariant identifies the zero current pivot with the next leading-prefix determinant.
One-step zero propagation for the singular row-pivoted Bareiss branch.
If the current k-bordered trailing pivot column is zero at every row at or
below k, then every (k + 1)-bordered minor one step deeper is zero. The
proof is the Desnanot-Jacobi recurrence: both numerator terms contain a zero
minor from the failed pivot column, and the previous leading-prefix pivot is
nonzero, so the next determinant must vanish.
Column-shaped form of borderedMinor_zero_column_succ_det_eq_zero_of_entries.
This is the API used by the singular row-pivoted Bareiss branch: failed pivot
search supplies a zero current pivot column, and the bordered-minor invariant
transports that to this determinant column hypothesis.
In the row-swap regular branch, the Hex determinant of the working matrix flips sign. This is the determinant-side row-swap fact needed by the row-pivoted Bareiss invariant.
Public regular swap-only step surface for the row-pivoted Bareiss proof.
When the current diagonal pivot is zero and findPivot? returns a later row,
the row-pivoted loop swaps source rows state.step and pivot before applying
the stepMatrix update. Under that source rewrite, the bordered-minor invariant
transports across the source row swap: the working matrix is rowSwap'd to
match, the row-swap counter increments, and state.step is unchanged.
The subsequent stepMatrix update is then handled by
bareissPivotInvariant_regular_no_swap applied to the swapped source.
Incrementing the row-swap counter flips the Bareiss sign.
Instances For
Row-pivoted Bareiss invariant. The current working state is interpreted as a no-pivot Bareiss state for a logical source obtained from the original source by the row swaps already performed; the sign field records the determinant relation back to the original source.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The initial row-pivoted Bareiss state satisfies the pivoted invariant with the original matrix as its logical source.
A regular row-pivoted Bareiss step that does not swap rows preserves the pivoted invariant.
A regular row-pivoted Bareiss step that swaps rows preserves the pivoted invariant.
Recursive row-pivoted Bareiss invariant. If a pivotLoop run finishes with
no singular step, then the final state still satisfies the pivoted invariant.
The recursive no-pivot Bareiss invariant: starting from any state that
satisfies BareissNoPivotInvariant, if every future leading-prefix determinant
(from state.step up to n) is nonzero, then the invariant continues to hold
after running noPivotLoop for any amount of fuel.
Under NonzeroBareissPivots, the no-pivot Bareiss recurrence run from the
initial state satisfies the bordered-minor invariant.
Immediate consequence of the bordered-minor invariant: under
NonzeroBareissPivots, the no-pivot Bareiss recurrence never takes the
singular branch.
Public corollary: under NonzeroBareissPivots, the executable no-pivot
Bareiss data records no singular step.
Outcome-driven companion of noPivotLoop_invariant: if the no-pivot
Bareiss loop run from a valid invariant state does NOT record a singular step
during its fuel iterations, the invariant continues to hold afterward. The
non-singular outcome guarantees every visited pivot was nonzero, which is the
hypothesis the inductive step needs.
This is the no-pivot analog of pivotLoop_invariant_of_singularStep_eq_none.
Capstone: under NonzeroBareissPivots, the no-pivot Bareiss recurrence
computes the Mathlib determinant of the source matrix.
Failed Bareiss column dependence #
Helper for the row-pivoted singular Bareiss branch: if the pivot search at
level k fails (the entire k-bordered trailing column is zero) and the
preceding leading-prefix determinant is nonzero, then there is an explicit
linear combination of the columns of source — with coefficients given by the
signed k × k cofactors of the leading prefix augmented with column k —
that vanishes at every row. The coefficient on column k is
Hex.Matrix.det (Hex.Matrix.principalSubmatrix source k _), which is nonzero by
hypothesis. The follow-up issue closes the determinant via
Matrix.det_updateCol_sum and the duplicate-column determinant identity.
The k × (k+1) top block used to define the failed-pivot column
dependence: leading k rows of source, restricted to columns 0..k-1
followed by column k.
Equations
- HexMatrixMathlib.failedBareissTopBlock source k hk s c = if hc : ↑c < k then HexMatrixMathlib.matrixEquiv source ⟨↑s, ⋯⟩ ⟨↑c, ⋯⟩ else HexMatrixMathlib.matrixEquiv source ⟨↑s, ⋯⟩ ⟨k, hk⟩
Instances For
Coefficient function for the failed-pivot column dependence. The value at
c is (-1)^(k + c.val) * det(failedBareissTopBlock with column c removed) for
c.val ≤ k and 0 otherwise. The coefficient on column k is
det (principalSubmatrix source k _); see failedBareissColumn_at_pivot.
Equations
Instances For
Failed Bareiss column dependence.
If the leading-prefix determinant of source at size k is nonzero, and the
k-bordered minors with trailing column ⟨k, _⟩ all vanish for trailing rows
at or beyond k, then there is an explicit linear combination of the columns
of source — vanishing in every row — whose coefficient on column k equals
the leading-prefix determinant (and is therefore nonzero). The coefficients on
columns past k are zero.
The construction is the standard cofactor/adjugate trick: cofactor expansion
along the last row of the (k+1)-bordered minors yields the coefficient
function failedBareissColumn.
Failed Bareiss column ⟹ source determinant is zero.
If the leading-prefix determinant of source at size k is nonzero but every
k-bordered minor with trailing column ⟨k, _⟩ and trailing row at or below
k vanishes, then Hex.Matrix.det source = 0.
This is the Mathlib-side theorem consumed by the row-pivoted singular Bareiss
packaging: failed pivot search at level k produces a zero pivot column,
which the bordered-minor invariant transports to the determinant column
hypothesis here. The proof obtains a nonzero kernel vector for
matrixEquiv source from failed_bareiss_column_dependence, then closes the
determinant via Matrix.exists_mulVec_eq_zero_iff.
If row-pivoted Bareiss pivot search fails in a state satisfying the pivoted invariant, then the original source determinant is zero.
If a row-pivoted Bareiss loop reaches any singular step from a state satisfying the pivoted invariant, then the original source determinant is zero.
Some specific singular step recorded by pivotLoop forces the source
determinant to be zero.
The public row-pivoted Bareiss loop, started from the initial state, records a singular step only when the input determinant is zero.
Data-facing singular branch theorem for the final row-pivoted Bareiss capstone.
Mathlib-side correctness theorem for the packaged row-pivoted Bareiss
data: its .det field equals Mathlib's determinant of the corresponding
matrix. Proven directly here by combining the row-pivot invariant with the
singular-branch determinant-zero theorem above.
Row-pivoted Bareiss determinant soundness, exposed against Mathlib's determinant for downstream Mathlib-side callers.
Off-step generalisation of the no-pivot Bareiss bordered-minor
identification. After k + 1 no-pivot Bareiss iterations on M, every entry
at (a, c) with k + 1 ≤ a.val, c.val equals the determinant of the
(k + 2) × (k + 2) bordered minor of M with trailing row a and column
c, provided the partial loop records no singular step.
Composes noPivotLoop_invariant_of_singularStep_eq_none (the invariant
propagates through a non-singular partial pass), BareissNoPivotInvariant
(the trailing-block entries equal bordered-minor determinants), and
noPivotLoop_step_eq_add_of_singularStep_none (the partial pass advances
step by exactly the fuel consumed).