1-- Canonical finite-set iterated sums and their enumeration bridge (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.Ring.FiniteDoubleSum8import DoubleSum910defgraph finiteRowWeights (D E A w x : Set) (y ∈ E) : A := w((x, y))11requires matrix : w : D × E → A12requires row : x ∈ D13proof14have pair := product.pair at x, y, D, E with*15exact FunctionBetween.apply_closed at w, D × E, A, (x, y) with*1617defgraph finiteRowSums (D E A add zero neg mul one w : Set) (x ∈ D) : A :=18 finiteRingSum(E, A, add, zero, neg, mul, one, finiteRowWeights(D, E, A, w, x))19requiresring : IsCommRing(A, add, zero, neg, mul, one)20requires finiteE : Finite(E)21requires matrix : w : D × E → A22proof23have weights := finiteRowWeights.function at D, E, A, w, x with*24exact finiteRingSum.closed at E, A, add, zero, neg, mul, one, finiteRowWeights(D, E, A, w, x) with*2526def finiteDoubleSum (D E A add zero neg mul one w : Set) : Set:=27 finiteRingSum(D, A, add, zero, neg, mul, one, finiteRowSums(D, E, A, add, zero, neg, mul, one, w))2829defgraph enumeratedMatrix (m n D E A w f g : Set) (p ∈ m × n) : A :=30 w(productMap(f, g, m, n, D, E)(p))31requires matrix : w : D × E → A32requires rows : f : m → D33requires columns : g : n → E34proof35have rectangle := productMap.function with rows, columns36have pair := FunctionBetween.apply_closed at productMap(f, g, m, n, D, E), m × n, D × E, p with*37exact FunctionBetween.apply_closed at w, D × E, A, productMap(f, g, m, n, D, E)(p) with*3839theorem enumeratedMatrix.pair (m n D E A w f g i j : Set)40requires matrix : w : D × E → A41requires rows : f : m → D42requires columns : g : n → E43requires row : i ∈ m44requires column : j ∈ n45shows enumeratedMatrix(m, n, D, E, A, w, f, g)((i, j)) = w((f(i), g(j)))46proof47have pair := product.pair at i, j, m, n with*48have value := enumeratedMatrix.value at m, n, D, E, A, w, f, g, (i, j) with*49have mapped := productMap.apply at f, g, m, n, D, E, i, j with*50cc5152theorem ringRowSum.as_indexed (w v f add zero x : Set, n : Nat)53shows (∀ j ∈ n, w((x, j)) = v(f(j))) →54 ringRowSum(w, add, zero, x, n) = indexedRingSum(v, f, add, zero, n)55proof56induction n57| zero =>58intro values59simp [ringRowSum, indexedRingSum]60| succ(k) using ih =>61intro values62haveprefix : ∀ j ∈ k, w((x, j)) = v(f(j))63intros j hj64have included := membership.into_successor at j, k with*65exact values with j, included66have last := values with k, membership.self_successor at k with*67have previous := ih withprefix68rw [ringRowSum, indexedRingSum, previous, last]69rfl7071theorem ringDoubleSum.as_indexed (w v f add zero : Set, m n : Nat)72shows (∀ i ∈ m, ringRowSum(w, add, zero, i, n) = v(f(i))) →73 ringDoubleSum(w, add, zero, m, n) = indexedRingSum(v, f, add, zero, m)74proof75induction m76| zero =>77intro values78simp [ringDoubleSum, indexedRingSum]79| succ(k) using ih =>80intro values81haveprefix : ∀ i ∈ k, ringRowSum(w, add, zero, i, n) = v(f(i))82intros i hi83have included := membership.into_successor at i, k with*84exact values with i, included85have last := values with k, membership.self_successor at k with*86have previous := ih withprefix87rw [ringDoubleSum, indexedRingSum, previous, last]88rfl8990theorem finiteDoubleSum.closed (D E A add zero neg mul one w : Set)91requiresring : IsCommRing(A, add, zero, neg, mul, one)92requires finiteD : Finite(D)93requires finiteE : Finite(E)94requires matrix : w : D × E → A95shows finiteDoubleSum(D, E, A, add, zero, neg, mul, one, w) ∈ A96proof97have rows := finiteRowSums.function at D, E, A, add, zero, neg, mul, one, w with*98unfold finiteDoubleSum99exact finiteRingSum.closed with*100101theorem finiteDoubleSum.enumerations (D E A add zero neg mul one w f g : Set, m n : Nat)102requiresring : IsCommRing(A, add, zero, neg, mul, one)103requires finiteE : Finite(E)104requires matrix : w : D × E → A105requires enumD : BijectiveBetween(f, m, D)106requires enumE : BijectiveBetween(g, n, E)107shows finiteDoubleSum(D, E, A, add, zero, neg, mul, one, w) = ringDoubleSum(enumeratedMatrix(m, n, D, E, A, w, f, g), add, zero, m, n)108proof109have injD := Bijective.injective with enumD110have injE := Bijective.injective with enumE111have rows := Injective.function with injD112have columns := Injective.function with injE113have rowSums := finiteRowSums.function at D, E, A, add, zero, neg, mul, one, w with*114have outer := finiteRingSum.enumeration at D, A, add, zero, neg, mul, one, finiteRowSums(D, E, A, add, zero, neg, mul, one, w), f, m with*115have rowValues : ∀ i ∈ m, ringRowSum(enumeratedMatrix(m, n, D, E, A, w, f, g), add, zero, i, n) = finiteRowSums(D, E, A, add, zero, neg, mul, one, w)(f(i))116intros i hi117have row := FunctionBetween.apply_closed at f, m, D, i with*118have weights := finiteRowWeights.function at D, E, A, w, f(i) with*119have inner := finiteRingSum.enumeration at E, A, add, zero, neg, mul, one, finiteRowWeights(D, E, A, w, f(i)), g, n with*120have values : ∀ j ∈ n, enumeratedMatrix(m, n, D, E, A, w, f, g)((i, j)) = finiteRowWeights(D, E, A, w, f(i))(g(j))121intros j hj122have column := FunctionBetween.apply_closed at g, n, E, j with*123haveleft:= enumeratedMatrix.pair at m, n, D, E, A, w, f, g, i, j with*124haveright:= finiteRowWeights.value at D, E, A, w, f(i), g(j) with*125cc126have bridge := ringRowSum.as_indexed at enumeratedMatrix(m, n, D, E, A, w, f, g), finiteRowWeights(D, E, A, w, f(i)), g, add, zero, i, n with*127have equal := bridge with values128have value := finiteRowSums.value at D, E, A, add, zero, neg, mul, one, w, f(i) with*129cc130have bridge := ringDoubleSum.as_indexed at enumeratedMatrix(m, n, D, E, A, w, f, g), finiteRowSums(D, E, A, add, zero, neg, mul, one, w), f, add, zero, m, n with*131have equal := bridge with rowValues132unfold finiteDoubleSum133cc134135theorem finiteDoubleSum.interchange (D E A add zero neg mul one w : Set)136requiresring : IsCommRing(A, add, zero, neg, mul, one)137requires finiteD : Finite(D)138requires finiteE : Finite(E)139requires matrix : w : D × E → A140shows finiteDoubleSum(D, E, A, add, zero, neg, mul, one, w) =141 finiteDoubleSum(E, D, A, add, zero, neg, mul, one, transposedMatrix(D, E, A, w))142proof143obtain⟨m, naturalM, f, enumD⟩:= Finite.enumeration with finiteD144obtain⟨n, naturalN, g, enumE⟩:= Finite.enumeration with finiteE145have injD := Bijective.injective with enumD146have injE := Bijective.injective with enumE147have rows := Injective.function with injD148have columns := Injective.function with injE149have transposed := transposedMatrix.function at D, E, A, w with*150have first := enumeratedMatrix.function at m, n, D, E, A, w, f, g with*151have second := enumeratedMatrix.function at n, m, E, D, A, transposedMatrix(D, E, A, w), g, f with*152have valuesW := RingMatrixValues.of_function with first153have valuesV := RingMatrixValues.of_function with second154have entries : TransposedValues(enumeratedMatrix(m, n, D, E, A, w, f, g), enumeratedMatrix(n, m, E, D, A, transposedMatrix(D, E, A, w), g, f), m, n)155intros i hi j hj156have row := FunctionBetween.apply_closed at f, m, D, i with*157have column := FunctionBetween.apply_closed at g, n, E, j with*158haveleft:= enumeratedMatrix.pair at m, n, D, E, A, w, f, g, i, j with*159haveright:= enumeratedMatrix.pair at n, m, E, D, A, transposedMatrix(D, E, A, w), g, f, j, i with*160have entry := transposedMatrix.pair at D, E, A, w, f(i), g(j) with*161cc162have interchange := ringDoubleSum.transpose at A, add, zero, neg, mul, one, enumeratedMatrix(m, n, D, E, A, w, f, g), enumeratedMatrix(n, m, E, D, A, transposedMatrix(D, E, A, w), g, f), m, n with*163have equal := interchange with valuesW, valuesV, entries164haveleft:= finiteDoubleSum.enumerations at D, E, A, add, zero, neg, mul, one, w, f, g, m, n with*165haveright:= finiteDoubleSum.enumerations at E, D, A, add, zero, neg, mul, one, transposedMatrix(D, E, A, w), g, f, n, m with*166cc167