1-- Single-index coefficient maps and their exact support (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.CoefficientSingle8import Coefficients910defunique singleValue (A z a j i : Set) (value ∈ A) :=11 (i = j → value = a) ∧ (i ≠ j → value = z)12requires zeroIn : z ∈ A13requires coefficient : a ∈ A14proof15have casesI : i = j ∨ i ≠ j16tauto17cases casesI with same | different18 . witness a19refine⟨coefficient, _, _⟩20 . intro equal21rfl22 . intro impossible23exfalso24exact impossible with same25 . witness z26refine⟨zeroIn, _, _⟩27 . intro impossible28exfalso29exact different with impossible30 . intro unequal31rfl32uniqueness33intros u uIn first v vIn second34have casesI : i = j ∨ i ≠ j35tauto36cases casesI with same | different37 . have uValue : u = a38tauto39have vValue : v = a40tauto41cc42 . have uValue : u = z43tauto44have vValue : v = z45tauto46cc4748theorem singleValue.closed (A z a j i : Set)49requires zeroIn : z ∈ A50requires coefficient : a ∈ A51shows singleValue(A, z, a, j, i) ∈ A52proof53have selected := singleValue.selected at A, z, a, j, i with*54exact selected.left5556theorem singleValue.same (A z a j i : Set)57requires zeroIn : z ∈ A58requires coefficient : a ∈ A59requires equal : i = j60shows singleValue(A, z, a, j, i) = a61proof62have selected := singleValue.selected at A, z, a, j, i with*63tauto6465theorem singleValue.other (A z a j i : Set)66requires zeroIn : z ∈ A67requires coefficient : a ∈ A68requires different : i ≠ j69shows singleValue(A, z, a, j, i) = z70proof71have selected := singleValue.selected at A, z, a, j, i with*72tauto7374-- Selecting a zero coefficient remains zero for either branch.75theorem singleValue.zero (A z j i : Set)76requires zeroIn : z ∈ A77shows singleValue(A, z, z, j, i) = z78proof79have alternatives : i = j ∨ i ≠ j bytauto80cases alternatives with same | different81 . exact singleValue.same with*82 . exact singleValue.other with*8384-- Filtering before grouping agrees with filtering the selected group.85theorem singleValue.iterated (A z a k x c b : Set)86requires zeroIn : z ∈ A87requires coefficient : a ∈ A88shows singleValue(A, z, singleValue(A, z, a, k(x), b), x, c) =89 singleValue(A, z, singleValue(A, z, a, x, c), k(c), b)90proof91have alternatives : c = x ∨ c ≠ x bytauto92cases alternatives with same | different93 . haveleft:= singleValue.same at A, z, singleValue(A, z, a, k(x), b), x, c with*94haveright:= singleValue.same at A, z, a, x, c with*95cc96 . haveleft:= singleValue.other at A, z, singleValue(A, z, a, k(x), b), x, c with*97have innerRight := singleValue.other at A, z, a, x, c with*98haveright:= singleValue.zero at A, z, k(c), b with*99cc100101defgraph coefficientSingle (I A z a j : Set) (i ∈ I) : A := singleValue(A, z, a, j, i)102requires zeroIn : z ∈ A103requires coefficient : a ∈ A104proof105exact singleValue.closed with*106107theorem coefficientSingle.same (I A z a j : Set)108requires zeroIn : z ∈ A109requires coefficient : a ∈ A110requires index : j ∈ I111shows coefficientSingle(I, A, z, a, j)(j) = a112proof113have value := coefficientSingle.value at I, A, z, a, j, j with*114have equal : j = j byrfl115have selected := singleValue.same at A, z, a, j, j with*116cc117118theorem coefficientSingle.other (I A z a j i : Set)119requires zeroIn : z ∈ A120requires coefficient : a ∈ A121requires index : i ∈ I122requires different : i ≠ j123shows coefficientSingle(I, A, z, a, j)(i) = z124proof125have value := coefficientSingle.value at I, A, z, a, j, i with*126have selected := singleValue.other at A, z, a, j, i with*127cc128129theorem coefficientSingle.support_membership (I A z a j i : Set)130requires zeroIn : z ∈ A131requires coefficient : a ∈ A132shows i ∈ functionSupport(coefficientSingle(I, A, z, a, j), I, z) ↔ i ∈ I ∧ i = j ∧ a ≠ z133proof134constructor135 . intro member136have data := functionSupport.membership.forward with member137have equal : i = j138have alternatives : i = j ∨ i ≠ j bytauto139cases alternatives with same | different140 . exact same141 . have value := coefficientSingle.other at I, A, z, a, j, i with*142havecontradiction:= data.right with value143tauto144have nonzero : a ≠ z145intro vanishes146have atIndex : j ∈ I147rw← equal148exact data.left149have value := coefficientSingle.same at I, A, z, a, j with*150have vanishing : coefficientSingle(I, A, z, a, j)(i) = z bycc151exact data.right with vanishing152refine⟨data.left, equal, nonzero⟩153 . intro data154rcases data with⟨index, equal, nonzero⟩155have atIndex : j ∈ I by rwa ← equal156have value := coefficientSingle.same at I, A, z, a, j with*157have different : coefficientSingle(I, A, z, a, j)(i) ≠ z158intro vanishing159have impossible : a = z bycc160exact nonzero with impossible161exact functionSupport.membership.backward with⟨index, different⟩162163theorem coefficientSingle.support (I A z a j : Set)164requires zeroIn : z ∈ A165requires coefficient : a ∈ A166shows functionSupport(coefficientSingle(I, A, z, a, j), I, z) ⊆ {j}167proof168intros i hi169have data := coefficientSingle.support_membership.forward with*170exact singleton.membership.backward with data.right.left171172theorem CoefficientMap.single (I A z a j : Set)173requires zeroIn : z ∈ A174requires coefficient : a ∈ A175shows CoefficientMap(coefficientSingle(I, A, z, a, j), I, A, z)176proof177have function := coefficientSingle.function at I, A, z, a, j with*178have support := coefficientSingle.support at I, A, z, a, j with*179have finiteSingleton := Finite.singleton at j180have finite := Finite.subset with finiteSingleton, support181unfold CoefficientMap182refine⟨function, finite⟩183184theorem coefficientSingle.support_nonzero (I A z a j : Set)185requires zeroIn : z ∈ A186requires coefficient : a ∈ A187requires index : j ∈ I188requires nonzero : a ≠ z189shows functionSupport(coefficientSingle(I, A, z, a, j), I, z) = {j}190proof191ext i192constructor193 . intro member194have data := coefficientSingle.support_membership.forward with*195exact singleton.membership.backward with data.right.left196 . intro member197have equal := singleton.membership.forward with member198rw equal199apply coefficientSingle.support_membership.backward with zeroIn, coefficient200refine⟨index, rfl, nonzero⟩201