1-- Pairwise cancellation of finite sums, valid in every characteristic (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.Cancellation8import SumSupport9import Set.Involution1011section Sums12variable (D A add zero neg mul one w : Set)13notationring R := (A, add, zero, neg, mul, one)14hypothesisring : IsCommRing(R)15hypothesis weights : w : D → A1617theorem finiteRingSum.remove (V a : Set)18requires finite : Finite(V)19requires subset : V ⊆ D20requires member : a ∈ V21shows finiteRingSum(V, A, add, zero, neg, mul, one, restrict(w, V)) =22 R[finiteRingSum(V ∖ {a}, A, add, zero, neg, mul, one, restrict(w, V ∖ {a})) + w(a)]23proof24have restSubset : V ∖ {a} ⊆ V bysimp [Subset, difference.membership]25have smaller := Finite.subset with finite, restSubset26have fresh : ¬(a ∈ V ∖ {a}) bysimp [difference.membership, singleton.membership]27have restore := insert.restore with member28have restricted := restrict.domain_function with weights, subset29have expanded : restrict(w, V) : insert(a, V ∖ {a}) → A by rwa restore30have equation := finiteRingSum.insert with*31have nested := restrict.nested at w, V ∖ {a}, V with restSubset32have value := restrict.domain_apply with*33 rwa [restore, nested, value] at equation3435-- Remove one complete orbit. Fixed points must vanish separately: in36-- characteristic two, a value being its own negative does not imply zero.37theorem finiteRingSum.remove_orbit (V a b : Set)38requires finite : Finite(V)39requires subset : V ⊆ D40requires first : a ∈ V41requires second : b ∈ V42requires opposite : w(b) = R[-w(a)]43requires fixed : b = a → w(a) = R[0]44shows finiteRingSum(V, A, add, zero, neg, mul, one, restrict(w, V)) =45 finiteRingSum((V ∖ {a}) ∖ {b}, A, add, zero, neg, mul, one, restrict(w, (V ∖ {a}) ∖ {b}))46proof47have restSubset : V ∖ {a} ⊆ V bysimp [Subset, difference.membership]48have restDomain := Subset.transitive with restSubset, subset49have finiteRest := Finite.subset with finite, restSubset50have pairedSubset : (V ∖ {a}) ∖ {b} ⊆ V ∖ {a} bysimp [Subset, difference.membership]51have pairedDomain := Subset.transitive with pairedSubset, restDomain52have finitePair := Finite.subset with finiteRest, pairedSubset53have pairWeights := restrict.domain_function with weights, pairedDomain54have pairValue := finiteRingSum.closed withring, finitePair, pairWeights55have aIn : a ∈ D bysimp [Subset]56have value := FunctionBetween.apply_closed with weights, aIn57have removed := finiteRingSum.remove at D, A, add, zero, neg, mul, one, w, V, a with*58have alternatives : b = a ∨ b ≠ a bytauto59cases alternatives with same | different60 . have vanishes := fixed with same61have unchanged : (V ∖ {a}) ∖ {b} = V ∖ {a}62rw same63ext y64simp [difference.membership]65rw unchanged66have restWeights := restrict.domain_function with weights, restDomain67have restValue := finiteRingSum.closed withring, finiteRest, restWeights68rw [removed, vanishes]69ring70 . have member : b ∈ V ∖ {a}71simp [difference.membership, singleton.membership]72have removedAgain := finiteRingSum.remove at D, A, add, zero, neg, mul, one, w, V ∖ {a}, b with*73rw [removed, removedAgain, opposite]74ring7576-- A list supplies finite induction only; it need not enumerate without repeats.77theorem finiteRingSum.involution_cover (t : Set) (xs : List(D))78requires involution : InvolutionOn(t, D)79requires opposite : ∀ a ∈ D, w(t(a)) = R[-w(a)]80requires fixed : ∀ a ∈ D, t(a) = a → w(a) = R[0]81shows∀ V, V ⊆ D → V ⊆ listSupport{D}(xs) → (∀ a ∈ V, t(a) ∈ V) →82 finiteRingSum(V, A, add, zero, neg, mul, one, restrict(w, V)) = R[0]83proof84induction xs85| List.nil =>86intros V subset covered closed87rw listSupport at covered88have empty : V =∅89apply Subset.antisymmetric with covered90exact empty.subset91rw empty92have bounded := empty.subset at D93have restricted := restrict.domain_function with weights, bounded94exact finiteRingSum.empty withring, restricted95| List.cons(a, tail) using ih =>96intros V subset covered closed97rw listSupport at covered98have finiteSupport := listSupport.finite at D, List.cons{D}(a, tail) with*99rw listSupport at finiteSupport100have finite := Finite.subset with finiteSupport, covered101have alternatives : a ∈ V ∨¬(a ∈ V) bytauto102cases alternatives with present | absent103 . have partner := closed with a, present104have pairedClosed := InvolutionOn.remove_pair with involution, subset, closed, present105have pairedSubset : (V ∖ {a}) ∖ {t(a)} ⊆ D bysimp [Subset, difference.membership]106have pairedCovered : (V ∖ {a}) ∖ {t(a)} ⊆ listSupport{D}(tail)107intros y member108have outer := difference.membership.forward with member109have inner := difference.membership.forward with outer.left110have includes := covered111have inserted := includes with y, inner.left112have choices := insert.membership.forward with inserted113cases choices with same | inTail114 . exfalso115have singleton := singleton.membership.backward with same116exact inner.right with singleton117 . exact inTail118have previous := ih with (V ∖ {a}) ∖ {t(a)}, pairedSubset, pairedCovered, pairedClosed119have aIn : a ∈ D byassumption120have negative := opposite with a, aIn121have fixedValue := fixed with a, aIn122have removed := finiteRingSum.remove_orbit at D, A, add, zero, neg, mul, one, w, V, a, t(a) with*123cc124 . have smaller : V ⊆ listSupport{D}(tail)125intros y member126have includes := covered127have inserted := includes with y, member128have choices := insert.membership.forward with inserted129cases choices with same | inTail130 . exfalso131rw same at member132exact absent with member133 . exact inTail134exact ih with V, subset, smaller, closed135136theorem finiteRingSum.involution (t : Set)137requires finite : Finite(D)138requires involution : InvolutionOn(t, D)139requires opposite : ∀ a ∈ D, w(t(a)) = R[-w(a)]140requires fixed : ∀ a ∈ D, t(a) = a → w(a) = R[0]141shows finiteRingSum(D, A, add, zero, neg, mul, one, w) = R[0]142proof143obtain⟨xs, list, covered⟩:= Finite.list_cover with finite144have reflexive : D ⊆ D bysimp [Subset]145have function := InvolutionOn.function with involution146have closed : ∀ a ∈ D, t(a) ∈ D147intros a member148exact FunctionBetween.apply_closed with function, member149have scan := finiteRingSum.involution_cover with*150have sum := scan with D, reflexive, covered, closed151have restricted := restrict.domain_function with weights, reflexive152have same : restrict(w, D) = w153apply FunctionBetween.ext with restricted, weights154intros a member155exact restrict.domain_apply with weights, reflexive, member156 rwa same at sum157158-- Common determinant/combinatorial case: the pairing has no fixed points.159theorem finiteRingSum.involution_free (t : Set)160requires finite : Finite(D)161requires involution : InvolutionOn(t, D)162requires opposite : ∀ a ∈ D, w(t(a)) = R[-w(a)]163requires free : ∀ a ∈ D, t(a) ≠ a164shows finiteRingSum(D, A, add, zero, neg, mul, one, w) = R[0]165proof166have fixed : ∀ a ∈ D, t(a) = a → w(a) = R[0]167intros a member same168exfalso169exact free with a, member, same170exact finiteRingSum.involution with*171172end Sums173