1-- The determinant of an affine polynomial matrix has a tracked Horner form (ZF).2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Algebra.Polynomial.AffineDeterminant8import HornerForms910section Rings11variable (I A add zero neg mul one j : Set)12notationring R := (A, add, zero, neg, mul, one)13notationring P := R[I]14hypothesisring : IsCommRing(R)1516-- det(B+XD) has a length-n Horner representation with terminal coefficient det(D).17theorem determinant.affine_horner (n : Nat) (M B D : Set)18requires matrixM : RingMatrix(n, P, M)19requires matrixB : RingMatrix(n, R, B)20requires matrixD : RingMatrix(n, R, D)21requires entries : ∀ r ∈ n, ∀ c ∈ n, M[r, c] = P[polynomialCoefficients(I, R)(B[r, c]) + polynomialCoefficients(I, R)(D[r, c]) * polynomialVariable(I, R, j)]22shows HornerForm(I, R, j, determinant(n, P, M), n, determinant(n, R, D))23proof24have finite := Finite.natural at n with*25have permutationsFinite := permutations.finite with finite26have target := polynomials.comm_ring at I, A, add, zero, neg, mul, one with*27have hom := polynomialCoefficients.hom at I, A, add, zero, neg, mul, one with*28have size := cardinality.natural at n with*29have polynomialTerms := determinantTerms.function at n, P, polynomialAdd(I, R), P[0], polynomialNeg(I, R), polynomialMul(I, R), P[1], M with*30have coefficientTerms := determinantTerms.function at n, A, add, zero, neg, mul, one, D with*31have forms : ∀ p ∈ permutations(n), HornerForm(I, R, j, determinantTerms(n, P, M)(p), n, determinantTerms(n, R, D)(p))32intros p hp33have permutation := permutations.mem_iff.forward with hp34have injective := Bijective.injective with permutation35have function := Injective.function with injective36have polynomialEntries := permutationEntries.function at n, P, M, p with*37have constantEntries := permutationEntries.function at n, A, B, p with*38have slopeEntries := permutationEntries.function at n, A, D, p with*39have affine : ∀ r ∈ n, permutationEntries(n, P, M, p)(r) = P[polynomialCoefficients(I, R)(permutationEntries(n, R, B, p)(r)) + polynomialCoefficients(I, R)(permutationEntries(n, R, D, p)(r)) * polynomialVariable(I, R, j)]40intros r hr41have column := FunctionBetween.apply_closed at p, n, n, r with*42haveleft:= permutationEntries.value at n, P, M, p, r with*43have constant := permutationEntries.value at n, A, B, p, r with*44have slope := permutationEntries.value at n, A, D, p, r with*45have equation := entries with r, hr, p(r), column46cc47have product := HornerForm.finite_affine_product at I, A, add, zero, neg, mul, one, j, n, permutationEntries(n, P, M, p), permutationEntries(n, R, B, p), permutationEntries(n, R, D, p) with*48rw size at product49have mappedSign := permutationSign.map at A, add, zero, neg, mul, one, P, polynomialAdd(I, R), P[0], polynomialNeg(I, R), polynomialMul(I, R), P[1], polynomialCoefficients(I, R), n, p with*50have scaled := HornerForm.scale at I, A, add, zero, neg, mul, one, j, finiteRingProduct(n, P, permutationEntries(n, P, M, p)), n, permutationSign(n, R, p), finiteRingProduct(n, R, permutationEntries(n, R, D, p)) with*51have polynomialTerm := determinantTerms.value at n, P, polynomialAdd(I, R), P[0], polynomialNeg(I, R), polynomialMul(I, R), P[1], M, p with*52have coefficientTerm := determinantTerms.value at n, A, add, zero, neg, mul, one, D, p with*53 rwa [polynomialTerm, coefficientTerm, ← mappedSign]54have result := HornerForm.finite_sum at I, A, add, zero, neg, mul, one, j, n, permutations(n), determinantTerms(n, P, M), determinantTerms(n, R, D) with*55unfold determinant56exact result5758end Rings59