1-- Monomials as finitely supported natural-valued exponent maps (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.Monomial8import CoefficientSingle910def monomials (I : Set) : Set:= coefficientMaps(I, ℕ, 0)11def monomialOne (I : Set) : Set:= constantFunction(I, ℕ, 0)12def monomialVariable (I j : Set) : Set:= coefficientSingle(I, ℕ, 0, 1, j)1314theorem monomials.map (I m : Set)15requires member : m ∈ monomials(I)16shows CoefficientMap(m, I, ℕ, 0)17proof18unfold monomials at member19have data := coefficientMaps.membership.forward with member20exact data.right2122theorem monomials.contains (I m : Set)23requires map : CoefficientMap(m, I, ℕ, 0)24shows m ∈ monomials(I)25proof26unfold monomials27exact coefficientMaps.contains with map2829theorem monomials.function (I m : Set)30requires member : m ∈ monomials(I)31shows m : I → ℕ32proof33have map := monomials.map with member34exact CoefficientMap.function with map3536theorem monomials.exponent (I m i : Set)37requires member : m ∈ monomials(I)38requires index : i ∈ I39showsNat(m(i))40proof41have function := monomials.function with member42have value := FunctionBetween.apply_closed with function, index43exact nat.omega.backward with value4445theorem monomials.ext (I m n : Set)46requiresleft : m ∈ monomials(I)47requiresright : n ∈ monomials(I)48requires exponents : ∀ i ∈ I, m(i) = n(i)49shows m = n50proof51have functionM := monomials.function withleft52have functionN := monomials.function withright53exact FunctionBetween.ext with functionM, functionN, exponents5455theorem monomialOne.value (I i : Set)56requires index : i ∈ I57shows monomialOne(I)(i) =058proof59have zeroIn := nat.omega.forward with Naturals.constructor.zero60unfold monomialOne61exact constantFunction.apply with*6263theorem monomialOne.member (I : Set)64shows monomialOne(I) ∈ monomials(I)65proof66have zeroIn := nat.omega.forward with Naturals.constructor.zero67have function : monomialOne(I) : I → ℕ68unfold monomialOne69exact constantFunction.function with*70have support : functionSupport(monomialOne(I), I, 0) =∅71ext i72constructor73 . intro member74have data := functionSupport.membership.forward with member75have value := monomialOne.value with data.left76havecontradiction:= data.right with value77tauto78 . intro member79simp80apply monomials.contains81unfold CoefficientMap82refine⟨function, ?_⟩83rw support84exact Finite.empty8586theorem monomialVariable.member (I j : Set)87shows monomialVariable(I, j) ∈ monomials(I)88proof89have zeroIn := nat.omega.forward with Naturals.constructor.zero90have oneNat := Naturals.constructor.succ with Naturals.constructor.zero91have oneIn := nat.omega.forward with oneNat92have map := CoefficientMap.single at I, ℕ, 0, 1, j with*93apply monomials.contains94unfold monomialVariable95exact map9697theorem monomialVariable.same (I j : Set)98requires index : j ∈ I99shows monomialVariable(I, j)(j) =1100proof101have zeroIn := nat.omega.forward with Naturals.constructor.zero102have oneNat := Naturals.constructor.succ with Naturals.constructor.zero103have oneIn := nat.omega.forward with oneNat104unfold monomialVariable105exact coefficientSingle.same with*106107theorem monomialVariable.other (I j i : Set)108requires index : i ∈ I109requires different : i ≠ j110shows monomialVariable(I, j)(i) =0111proof112have zeroIn := nat.omega.forward with Naturals.constructor.zero113have oneNat := Naturals.constructor.succ with Naturals.constructor.zero114have oneIn := nat.omega.forward with oneNat115unfold monomialVariable116exact coefficientSingle.other with*117118defgraph monomialProduct (I m n : Set) (i ∈ I) : ℕ := m(i) + n(i)119requiresleft : m ∈ monomials(I)120requiresright : n ∈ monomials(I)121proof122have mNat := monomials.exponent at I, m, i with*123have nNat := monomials.exponent at I, n, i with*124have sumNat : Nat(m(i) + n(i)) bytypecheck125exact nat.omega.forward with sumNat126127theorem monomialProduct.support (I m n : Set)128requiresleft : m ∈ monomials(I)129requiresright : n ∈ monomials(I)130shows functionSupport(monomialProduct(I, m, n), I, 0) = functionSupport(m, I, 0) ∪ functionSupport(n, I, 0)131proof132ext i133constructor134 . intro member135have data := functionSupport.membership.forward with member136have value := monomialProduct.value at I, m, n, i with*137have mNat := monomials.exponent at I, m, i with*138have nNat := monomials.exponent at I, n, i with*139have zeroSum : m(i) =0→ n(i) =0→ m(i) + n(i) =0140intros mZero nZero141rw [mZero, nZero]142compute143have nonzeroSum : m(i) + n(i) ≠0144intro equal145have impossible : monomialProduct(I, m, n)(i) =0bycc146exact data.right with impossible147have memM := functionSupport.membership at m, I, 0, i148have memN := functionSupport.membership at n, I, 0, i149apply union2.membership.backward150tauto151 . intro member152have alternatives := union2.membership.forward with member153have memM := functionSupport.membership at m, I, 0, i154have memN := functionSupport.membership at n, I, 0, i155have index : i ∈ I bytauto156have mNat := monomials.exponent at I, m, i with*157have nNat := monomials.exponent at I, n, i with*158have value := monomialProduct.value at I, m, n, i with*159have bothZero := add.eq_zero at n(i), m(i) with*160have nonzero : monomialProduct(I, m, n)(i) ≠0161intro equal162have sumZero : m(i) + n(i) =0bycc163have zeros := bothZero with sumZero164tauto165exact functionSupport.membership.backward with⟨index, nonzero⟩166167theorem monomialProduct.member (I m n : Set)168requiresleft : m ∈ monomials(I)169requiresright : n ∈ monomials(I)170shows monomialProduct(I, m, n) ∈ monomials(I)171proof172have mapM := monomials.map withleft173have mapN := monomials.map withright174have finiteM := CoefficientMap.finite_support with mapM175have finiteN := CoefficientMap.finite_support with mapN176have finite := Finite.union with finiteM, finiteN177have support := monomialProduct.support withleft, right178have function := monomialProduct.function at I, m, n with*179apply monomials.contains180unfold CoefficientMap181refine⟨function, ?_⟩182 rwa support183184theorem monomialProduct.commutative (I m n : Set)185requiresleft : m ∈ monomials(I)186requiresright : n ∈ monomials(I)187shows monomialProduct(I, m, n) = monomialProduct(I, n, m)188proof189have productM := monomialProduct.member at I, m, n with*190have productN := monomialProduct.member at I, n, m with*191apply monomials.ext with productM, productN192intros i hi193have mNat := monomials.exponent at I, m, i with*194have nNat := monomials.exponent at I, n, i with*195have leftValue := monomialProduct.value at I, m, n, i with*196have rightValue := monomialProduct.value at I, n, m, i with*197rw [leftValue, rightValue]198exact add.commutative with*199200theorem monomialProduct.associative (I m n p : Set)201requires first : m ∈ monomials(I)202requires second : n ∈ monomials(I)203requires third : p ∈ monomials(I)204shows monomialProduct(I, monomialProduct(I, m, n), p) = monomialProduct(I, m, monomialProduct(I, n, p))205proof206have mn := monomialProduct.member at I, m, n with*207have np := monomialProduct.member at I, n, p with*208haveleft:= monomialProduct.member at I, monomialProduct(I, m, n), p with*209haveright:= monomialProduct.member at I, m, monomialProduct(I, n, p) with*210apply monomials.ext withleft, right211intros i hi212have mNat := monomials.exponent at I, m, i with*213have nNat := monomials.exponent at I, n, i with*214have pNat := monomials.exponent at I, p, i with*215have mnValue := monomialProduct.value at I, m, n, i with*216have npValue := monomialProduct.value at I, n, p, i with*217have leftValue := monomialProduct.value at I, monomialProduct(I, m, n), p, i with*218have rightValue := monomialProduct.value at I, m, monomialProduct(I, n, p), i with*219rw [leftValue, rightValue, mnValue, npValue]220exact add.associative with*221222theorem monomialProduct.one (I m : Set)223requires member : m ∈ monomials(I)224shows monomialProduct(I, m, monomialOne(I)) = m225proof226have unit := monomialOne.member at I227have product := monomialProduct.member at I, m, monomialOne(I) with*228apply monomials.ext with product, member229intros i hi230have mNat := monomials.exponent at I, m, i with*231have value := monomialProduct.value at I, m, monomialOne(I), i with*232have unitValue := monomialOne.value at I, i with*233rw [value, unitValue]234exact add.right_unit at m(i) with*235236theorem monomialProduct.cancel (I m n p : Set)237requires first : m ∈ monomials(I)238requires second : n ∈ monomials(I)239requires third : p ∈ monomials(I)240requires equal : monomialProduct(I, m, n) = monomialProduct(I, m, p)241shows n = p242proof243apply monomials.ext with second, third244intros i hi245have mNat := monomials.exponent at I, m, i with*246have nNat := monomials.exponent at I, n, i with*247have pNat := monomials.exponent at I, p, i with*248have leftValue := monomialProduct.value at I, m, n, i with*249have rightValue := monomialProduct.value at I, m, p, i with*250have sums : m(i) + n(i) = m(i) + p(i) bycc251exact add.left_cancel with mNat, sums252253defunique monomialPairProduct (I p : Set) (result ∈ monomials(I)) :=254∃ m ∈ monomials(I), ∃ n ∈ monomials(I), p = (m, n) ∧ result = monomialProduct(I, m, n)255requires pair : p ∈ monomials(I) × monomials(I)256proof257obtain⟨bound, m, hm, n, hn, shape⟩:= product.membership.forward with pair258have member := monomialProduct.member with hm, hn259refine⟨monomialProduct(I, m, n), member, m, hm, n, hn, shape, rfl⟩260uniqueness261intros u hu first v hv second262obtain⟨m, hm, n, hn, shapeU, valueU⟩:= first263obtain⟨q, hq, r, hr, shapeV, valueV⟩:= second264have pairs : (m, n) = (q, r) bycc265have coordinates := orderedPair.injective with pairs266cc267268defgraph monomialMul (I : Set) (p ∈ monomials(I) × monomials(I)) : monomials(I) := monomialPairProduct(I, p)269proof270have selected := monomialPairProduct.selected with member271exact selected.left272273theorem monomialMul.apply (I m n : Set)274requiresleft : m ∈ monomials(I)275requiresright : n ∈ monomials(I)276shows (monomialMul(I))(m, n) = monomialProduct(I, m, n)277proof278have pair := product.pair at m, n, monomials(I), monomials(I) with*279have selected := monomialPairProduct.selected with pair280obtain⟨q, hq, r, hr, shape, output⟩:= selected.right281have coordinates := orderedPair.injective with shape282have value := monomialMul.value with pair283unfold call2284cc285286theorem monomials.comm_monoid (I : Set)287shows IsCommMonoid(monomials(I), monomialMul(I), monomialOne(I))288proof289have operation := monomialMul.function at I290have unit := monomialOne.member at I291have associative : Associative(monomials(I), monomialMul(I))292intros m hm n hn p hp293have mn := monomialProduct.member with hm, hn294have np := monomialProduct.member with hn, hp295have leftInner := monomialMul.apply with hm, hn296have rightInner := monomialMul.apply with hn, hp297rw [leftInner, rightInner]298have leftOuter := monomialMul.apply at I, monomialProduct(I, m, n), p with*299have rightOuter := monomialMul.apply at I, m, monomialProduct(I, n, p) with*300rw [leftOuter, rightOuter]301exact monomialProduct.associative with*302have identity : Identity(monomials(I), monomialMul(I), monomialOne(I))303unfold Identity304refine⟨unit, ?_⟩305intros m hm306have leftValue := monomialMul.apply at I, monomialOne(I), m with*307have rightValue := monomialMul.apply at I, m, monomialOne(I) with*308have comm := monomialProduct.commutative at I, monomialOne(I), m with*309have identity := monomialProduct.one with hm310constructor311 . cc312 . cc313have commutative : Commutative(monomials(I), monomialMul(I))314intros m hm n hn315have leftValue := monomialMul.apply with hm, hn316have rightValue := monomialMul.apply with hn, hm317have comm := monomialProduct.commutative with hm, hn318cc319unfold IsCommMonoid320refine⟨?_, commutative⟩321unfold IsMonoid322refine⟨?_, identity⟩323unfold IsSemigroup324refine⟨?_, associative⟩325exact operation326327theorem monomialVariable.injective (I j k : Set)328requires first : j ∈ I329requires second : k ∈ I330requires equal : monomialVariable(I, j) = monomialVariable(I, k)331shows j = k332proof333have alternatives : j = k ∨ j ≠ k bytauto334cases alternatives with same | different335 . exact same336 . have valueJ := monomialVariable.same with first337have valueK := monomialVariable.other with first, different338have impossible : 0=1bycc339exfalso340exact Naturals.disjoint.zero.succ at0with impossible341