LeanToolchain.Math provides discrete linear algebra (length-indexed Vec, nested-list Matrix) with a growing lemma suite, plus ℝ-valued norm definitions in Norm.lean built on mathlib’s Real and sqrt. Proofs cover the properties stated in the Lean files (for example additive laws for Vec and selected matrix identities); they are not a complete textbook development of numerical linear algebra.
Rust helpers for floating-point vectors and matrices are generated alongside crypto (see development/extraction.md); they are template output for benchmarking and FFI-shaped experiments, not extracted proof terms.
Creates an empty vector of length 0.
Example:
let emptyVec : Vec Nat 0 := Vec.nilAdds an element to the front of a vector.
Parameters:
x : α- The element to addv : Vec α n- The vector to prepend to
Returns:
Vec α (n + 1)- The new vector with the element added
Example:
let v1 : Vec Nat 1 := Vec.cons 1 Vec.nil
let v2 : Vec Nat 2 := Vec.cons 2 v1
-- v2 is [2, 1]Creates a vector from a list with a proof that the list length matches the dimension.
Parameters:
data : List α- The list of elementsh : data.length = n- Proof that the list length equals the dimension
Returns:
Vec α n- The vector with the specified dimension
Example:
let data := [1, 2, 3, 4, 5]
let v := Vec.mk' data (by rfl)
-- v is a Vec Nat 5 containing [1, 2, 3, 4, 5]Creates a zero vector (all elements are 0).
Returns:
Vec α n- A vector of length n with all elements set to 0
Example:
let zeroVec : Vec Nat 3 := Vec.zero
-- zeroVec is [0, 0, 0]Gets the first element of a non-empty vector.
Parameters:
v : Vec α (n + 1)- A non-empty vector
Returns:
α- The first element
Example:
let v := Vec.cons 1 (Vec.cons 2 Vec.nil)
let first := v.head
-- first is 1Gets all elements except the first of a non-empty vector.
Parameters:
v : Vec α (n + 1)- A non-empty vector
Returns:
Vec α n- The vector without the first element
Example:
let v := Vec.cons 1 (Vec.cons 2 Vec.nil)
let rest := v.tail
-- rest is [2]Gets an element at a specific index.
Parameters:
v : Vec α n- The vectori : Fin n- The index (must be less than n)
Returns:
α- The element at the specified index
Example:
let v := Vec.mk' [1, 2, 3] (by rfl)
let element := v.get ⟨1, by simp⟩
-- element is 2Sets an element at a specific index.
Parameters:
v : Vec α n- The vectori : Fin n- The index (must be less than n)x : α- The new value
Returns:
Vec α n- The vector with the updated element
Example:
let v := Vec.mk' [1, 2, 3] (by rfl)
let v2 := v.set ⟨1, by simp⟩ 42
-- v2 is [1, 42, 3]Element-wise addition of two vectors.
Parameters:
v1 : Vec α n- First vectorv2 : Vec α n- Second vector
Returns:
Vec α n- The sum of the vectors
Example:
let v1 := Vec.mk' [1, 2, 3] (by rfl)
let v2 := Vec.mk' [4, 5, 6] (by rfl)
let sum := v1.add v2
-- sum is [5, 7, 9]Element-wise subtraction of two vectors.
Parameters:
v1 : Vec α n- First vectorv2 : Vec α n- Second vector
Returns:
Vec α n- The difference of the vectors
Example:
let v1 := Vec.mk' [4, 5, 6] (by rfl)
let v2 := Vec.mk' [1, 2, 3] (by rfl)
let diff := v1.sub v2
-- diff is [3, 3, 3]Scalar multiplication of a vector.
Parameters:
c : α- The scalarv : Vec β n- The vector
Returns:
Vec β n- The scaled vector
Example:
let v := Vec.mk' [1, 2, 3] (by rfl)
let scaled := v.smul 2
-- scaled is [2, 4, 6]Computes the dot product of two vectors.
Parameters:
v1 : Vec α n- First vectorv2 : Vec α n- Second vector
Returns:
α- The dot product
Example:
let v1 := Vec.mk' [1, 2, 3] (by rfl)
let v2 := Vec.mk' [4, 5, 6] (by rfl)
let dot := v1.dot v2
-- dot is 32 (1*4 + 2*5 + 3*6)Computes the magnitude squared of a vector.
Parameters:
v : Vec α n- The vector
Returns:
α- The magnitude squared (dot product with itself)
Example:
let v := Vec.mk' [3, 4] (by rfl)
let magSq := v.magSq
-- magSq is 25 (3*3 + 4*4)Converts a vector to a list.
Parameters:
v : Vec α n- The vector
Returns:
List α- The list representation
Example:
let v := Vec.mk' [1, 2, 3] (by rfl)
let list := v.toList
-- list is [1, 2, 3]There is no separate Vec.fromList helper: use Vec.mk' data h with h : data.length = n (often rfl when the list is literal).
Matrix.mk' : List (List α) → (data.length = m) → (∀ row, row ∈ data → row.length = n) → Matrix α m n
Creates a matrix from a list of lists with proofs about dimensions.
Parameters:
data : List (List α)- The matrix data as a list of rowsh : data.length = m- Proof that the number of rows equals mh' : ∀ row, row ∈ data → row.length = n- Proof that each row has length n
Returns:
Matrix α m n- The matrix
Example:
let data := [[1, 2], [3, 4]]
let mat := Matrix.mk' data rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
-- mat is a 2x2 matrixCreates a zero matrix (all elements are 0).
Returns:
Matrix α m n- A matrix with all elements set to 0
Example:
let zeroMat : Matrix Nat 2 2 := Matrix.zero
-- zeroMat is [[0, 0], [0, 0]]Creates an identity matrix.
Returns:
Matrix α n n- An n×n identity matrix
Example:
let idMat : Matrix Nat 2 2 := Matrix.identity
-- idMat is [[1, 0], [0, 1]]Gets an element at a specific position.
Parameters:
mat : Matrix α m n- The matrixi : Fin m- The row indexj : Fin n- The column index
Returns:
α- The element at position (i, j)
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let element := mat.get ⟨0, by simp⟩ ⟨1, by simp⟩
-- element is 2Sets an element at a specific position.
Parameters:
mat : Matrix α m n- The matrixi : Fin m- The row indexj : Fin n- The column indexx : α- The new value
Returns:
Matrix α m n- The matrix with the updated element
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let mat2 := mat.set ⟨0, by simp⟩ ⟨1, by simp⟩ 42
-- mat2 has 42 at position (0, 1)Gets a row of the matrix.
Parameters:
mat : Matrix α m n- The matrixi : Fin m- The row index
Returns:
Vec α n- The i-th row as a vector
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let row := mat.row ⟨0, by simp⟩
-- row is [1, 2]Gets a column of the matrix.
Parameters:
mat : Matrix α m n- The matrixj : Fin n- The column index
Returns:
Vec α m- The j-th column as a vector
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let col := mat.col ⟨0, by simp⟩
-- col is [1, 3]Element-wise addition of two matrices.
Parameters:
mat1 : Matrix α m n- First matrixmat2 : Matrix α m n- Second matrix
Returns:
Matrix α m n- The sum of the matrices
Example:
let mat1 := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let mat2 := Matrix.mk' [[5, 6], [7, 8]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let sum := mat1.add mat2
-- sum is [[6, 8], [10, 12]]Element-wise subtraction of two matrices.
Parameters:
mat1 : Matrix α m n- First matrixmat2 : Matrix α m n- Second matrix
Returns:
Matrix α m n- The difference of the matrices
Example:
let mat1 := Matrix.mk' [[5, 6], [7, 8]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let mat2 := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let diff := mat1.sub mat2
-- diff is [[4, 4], [4, 4]]Scalar multiplication of a matrix.
Parameters:
c : α- The scalarmat : Matrix β m n- The matrix
Returns:
Matrix β m n- The scaled matrix
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let scaled := mat.smul 2
-- scaled is [[2, 4], [6, 8]]Matrix multiplication.
Parameters:
mat1 : Matrix α m n- First matrix (m×n)mat2 : Matrix α n p- Second matrix (n×p)
Returns:
Matrix α m p- The product matrix (m×p)
Example:
let mat1 := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let mat2 := Matrix.mk' [[5, 6], [7, 8]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let product := mat1.mul mat2
-- product is [[19, 22], [43, 50]]Matrix-vector multiplication.
Parameters:
mat : Matrix α m n- The matrixvec : Vec α n- The vector
Returns:
Vec α m- The result vector
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let vec := Vec.mk' [5, 6] (by rfl)
let result := mat.mulVec vec
-- result is [17, 39]Vector-matrix multiplication.
Parameters:
vec : Vec α m- The vectormat : Matrix α m n- The matrix
Returns:
Vec α n- The result vector
Example:
let vec := Vec.mk' [1, 2] (by rfl)
let mat := Matrix.mk' [[3, 4], [5, 6]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let result := vec.mulMat mat
-- result is [13, 16]Transposes a matrix.
Parameters:
mat : Matrix α m n- The matrix
Returns:
Matrix α n m- The transposed matrix
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let transposed := mat.transpose
-- transposed is [[1, 3], [2, 4]]Computes the trace of a square matrix.
Parameters:
mat : Matrix α n n- The square matrix
Returns:
α- The trace (sum of diagonal elements)
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let trace := mat.trace
-- trace is 5 (1 + 4)Computes the determinant of a 2×2 matrix.
Parameters:
mat : Matrix α 2 2- The 2×2 matrix
Returns:
α- The determinant
Example:
let mat := Matrix.mk' [[1, 2], [3, 4]] rfl (by intro row h; rcases h with rfl | rfl <;> rfl)
let det := mat.det2x2
-- det is -2 (1*4 - 2*3)det— Bareiss fraction-free elimination,O(n³). RequiresBEqandDiv(field-like coefficients; preferRat/ floats for inversion-style work).detLaplace— Laplace expansion along the first row. Correct on rings without division; costO(n!). Prefer for tiny matrices or ring-theoretic arguments.
Gaussian elimination with partial pivoting over a field-like type (BEq + Div). Returns the number of nonzero pivots.
Gauss–Jordan inversion. Returns none when a pivot cannot be found (singular / numerically degenerate). Prefer coefficient types where division is exact (e.g. Rat); over Int, truncated division can lose information unless the matrix is unimodular.
Closed-form eigenvalues of a 2 × 2 matrix given a square-root operation. Monic characteristic polynomials are available for 2 × 2 and 3 × 3 (highest-degree coefficient first).
Real wrappers in Norm.lean:
eigenvalues1x1Real/eigenvalues2x2Real— exacteigenvaluesReal— exact forn ≤ 2; forn ≥ 3returns a singleton with the power-iteration dominant estimate (not a full spectrum)operatorNorm— induced 2-norm via sqrt of the largest eigenvalue ofAᵀA
Matrix.map lifts coefficients (e.g. Int to Rat). Prefer mat.map (↑ : Int → Rat) |>.inv for exact inverses; Gauss–Jordan over Int uses truncated division and is only reliable for unit pivots.
Many expected identities (dot product laws, full matrix ring laws, and so on) are standard algebraically but are not all stated or proved in the current LeanToolchain/Math files. Treat Vector.lean and Matrix.lean as the source of truth for what is actually in the library today; the lists below are design intent, not a guarantee of existing theorem declarations.
- Addition is commutative / associative on
AddCommSemigroup/AddMonoidcarriers (see proved lemmas inVector.lean). - Further facts about
smul,dot, andmagSqmay be added incrementally.
- Matrix addition behaves as a componentwise monoid where instances allow (see proved lemmas).
- Multiplication, determinant, rank, and inverse are defined operationally; algebraic identities may be added incrementally.
- Vector Operations: O(n) where n is the vector length
- Matrix Addition/Subtraction: O(m×n)
- Matrix Multiplication: O(m×n×p); columns of the right factor are precomputed once
- Determinant (
det): O(n³) Bareiss;detLaplaceis O(n!) - Rank / Inverse: O(min(m,n)·m·n) style Gaussian / Gauss–Jordan
- Matrix Transpose: O(m×n)
- Operator 2-norm: exact for 1–2 columns; power iteration on
AᵀAfor wider matrices
The implementation provides strong type safety:
- Dimension Checking: All operations preserve vector and matrix dimensions
- Index Bounds: All indexing operations use
Fintypes to ensure bounds safety - Type Constraints: Operations require appropriate typeclass instances (Add, Mul, Div, BEq, etc.)
Executable checks under LeanToolchain/Math/Tests/ assert concrete values (determinants, products, rank, unimodular inverses, Cauchy–Schwarz on integers) and are driven by lake test / lake exe mathTests.
Floating-point vector and matrix FFI-shaped helpers are emitted into the same rust/ crate as the crypto modules when you run lake exe extract. The matrix module includes add, multiply (ikj loop), transpose, Bareiss matrix_det, Gaussian matrix_rank, and Gauss–Jordan matrix_inv, with unit tests mirroring Lean vectors. They are not Lean-term extraction.
lake exe extract
cd rust
cargo test
cargo clippy --all-targets -- -D warningsSee development/extraction.md for the full picture.