Definitions/Def_MvFormalGroup_BigWittFrobenius.lean
Witt coordinates, Frobenius and -typical projector polynomial families
Work in one variable T over the ring \mathbb{Z}[a_0,a_1,\dots] of integral polynomials in countably many variables, with a_m written X m. The generic series genSeries is 1+\sum_{m\ge 0}a_mT^{m+1}. The auxiliary products killProd are defined recursively by killProd 0 = genSeries and \mathrm{killProd}(k+1) = \mathrm{killProd}(k)\cdot(1 - C(c_k)T^{k+1}), where c_k is the coefficient of T^{k+1} in killProd k; the Witt coordinate wittCoord k is exactly that coefficient c_k, so that 1+\sum_m a_mT^{m+1}=\prod_k(1-b_kT^{k+1})^{-1} with b_k= wittCoord k. Accompanying lemmas give b_0=a_0, the closed form killProd k = genSeries · ∏_{i<k}(1-C(b_i)T^{i+1}), the vanishing of the coefficients of T,\dots,T^{k} in killProd k, constant coefficient 1, and vanishing constant term of each b_k.
For weights, awt m = m+1; IsIsobaric n P is the predicate that for every j the coefficient of T^j in P is weighted homogeneous of weight nj for awt. It is closed under products, differences, powers and finite products, holds for genSeries and killProd with n=1, and yields that b_k is weighted homogeneous of weight k+1.
geomSeries c e is \sum_{q}c^qT^{eq}, the inverse of 1-cT^e for e\neq 0. With d_k=\gcd(k+1,n), frobFactor n k is \bigl(1-b_k^{\,n/d_k}T^{(k+1)/d_k}\bigr)^{-d_k}, and the Frobenius polynomial frobPoly n m is the coefficient of T^{m+1} in \prod_{k<n(m+1)} frobFactor n k; it is weighted homogeneous of weight n(m+1), has zero constant term for n\neq0, vanishes identically for n=0, and frobPoly 1 m = X m. The p-typical projector polynomials are projPoly p k = wittCoord (p^k-1), weighted homogeneous of weight p^k.
The ring homomorphism evalOmegaInv t specialises a_m\mapsto t^{m+1} coefficientwise, i.e. restricts to the curve (1-tT)^{-1}; under it genSeries becomes geomSeries t 1, b_k becomes t for k=0 and 0 otherwise, frobPoly n m becomes t^{n(m+1)} for n\neq0, and projPoly p k becomes t for k=0 and 0 otherwise when p\ge 2. Finally toFam R P reduces an integral polynomial modulo the canonical map \mathbb{Z}\to R and views it in MvPowerSeries ℕ R; the families wittCoordFam, frobFam n, projFam p so obtained have zero constant coefficients and are shown to be admissible for substitution (MvPowerSeries.HasSubst), the last for p\ge2, via the weight bounds coming from weighted homogeneity.
Relation to Mathlib
Mathlib supplies the ambient machinery used here — MvPolynomial, PowerSeries/MvPowerSeries with MvPowerSeries.subst and HasSubst, and IsWeightedHomogeneous — but not these coordinate polynomials for the big Witt formal group, its Frobenius operators or the p-typical projector; those are the project's own, and are unrelated to Mathlib's WittVector polynomials.
Where it is used
These families are the integral coordinate data for the big Witt formal group, whose group law is formalised in the companion module, and they provide the Frobenius endomorphisms and Cartier's p-typical projector in the form (families of power series with nilpotent-friendly substitution) in which homomorphisms out of the Witt formal groups are expressed further on in the formal-group layer of the development.
References
- M. Hazewinkel, Formal Groups and Applications, Pure and Applied Mathematics 78, Academic Press, 1978
- M. Lazard, Commutative Formal Groups, Lecture Notes in Mathematics 443, Springer, 1975
References are suggested automatically and have not been individually verified.
English text generated automatically from the Lean source; the Lean statement is authoritative.
- 496 lines
- 76 declarations
- used in the statements of 10 theorems and imported by 10 proofs
- imports 1 definition modules
Source file: Definitions/Def_MvFormalGroup_BigWittFrobenius.lean
Imports
Imported by
- no other definition module
Declarations
- def
MvFormalGroup.BigWittLaw.genSeries - theorem
MvFormalGroup.BigWittLaw.coeff_genSeries_zero - theorem
MvFormalGroup.BigWittLaw.coeff_genSeries_succ - theorem
MvFormalGroup.BigWittLaw.constantCoeff_genSeries - def
MvFormalGroup.BigWittLaw.killProd - def
MvFormalGroup.BigWittLaw.wittCoord - theorem
MvFormalGroup.BigWittLaw.killProd_zero - theorem
MvFormalGroup.BigWittLaw.killProd_succ - theorem
MvFormalGroup.BigWittLaw.wittCoord_eq - theorem
MvFormalGroup.BigWittLaw.wittCoord_zero - theorem
MvFormalGroup.BigWittLaw.killProd_eq_mul_prod - theorem
MvFormalGroup.BigWittLaw.constantCoeff_killProd - theorem
MvFormalGroup.BigWittLaw.coeff_mul_one_sub_C_mul_X_pow - theorem
MvFormalGroup.BigWittLaw.coeff_killProd_eq_zero - abbrev
MvFormalGroup.BigWittLaw.awt - def
MvFormalGroup.BigWittLaw.IsIsobaric - theorem
MvFormalGroup.BigWittLaw.IsIsobaric.coeff - theorem
MvFormalGroup.BigWittLaw.isIsobaric_one - theorem
MvFormalGroup.BigWittLaw.IsIsobaric.mul - theorem
MvFormalGroup.BigWittLaw.IsIsobaric.sub - theorem
MvFormalGroup.BigWittLaw.IsIsobaric.prod - theorem
MvFormalGroup.BigWittLaw.IsIsobaric.pow - theorem
MvFormalGroup.BigWittLaw.isIsobaric_C_mul_X_pow - theorem
MvFormalGroup.BigWittLaw.isIsobaric_genSeries - theorem
MvFormalGroup.BigWittLaw.isIsobaric_killProd - theorem
MvFormalGroup.BigWittLaw.isWeightedHomogeneous_wittCoord - theorem
MvFormalGroup.BigWittLaw.constantCoeff_wittCoord - def
MvFormalGroup.BigWittLaw.geomSeries - theorem
MvFormalGroup.BigWittLaw.coeff_geomSeries - theorem
MvFormalGroup.BigWittLaw.constantCoeff_geomSeries - theorem
MvFormalGroup.BigWittLaw.one_sub_C_mul_X_pow_mul_geomSeries - def
MvFormalGroup.BigWittLaw.frobFactor - def
MvFormalGroup.BigWittLaw.frobPoly - theorem
MvFormalGroup.BigWittLaw.constantCoeff_frobFactor - theorem
MvFormalGroup.BigWittLaw.isIsobaric_geomSeries - theorem
MvFormalGroup.BigWittLaw.isIsobaric_frobFactor - theorem
MvFormalGroup.BigWittLaw.isWeightedHomogeneous_frobPoly - theorem
MvFormalGroup.BigWittLaw.constantCoeff_frobPoly - theorem
MvFormalGroup.BigWittLaw.frobPoly_zero_left - theorem
MvFormalGroup.BigWittLaw.genSeries_eq_killProd_mul_prod_geomSeries - theorem
MvFormalGroup.BigWittLaw.coeff_prod_geomSeries_wittCoord - theorem
MvFormalGroup.BigWittLaw.frobFactor_one - theorem
MvFormalGroup.BigWittLaw.frobPoly_one - def
MvFormalGroup.BigWittLaw.evalOmegaInv - theorem
MvFormalGroup.BigWittLaw.coeff_evalOmegaInv - theorem
MvFormalGroup.BigWittLaw.evalOmegaInv_genSeries - theorem
MvFormalGroup.BigWittLaw.evalOmegaInv_C_mul_X_pow - theorem
MvFormalGroup.BigWittLaw.evalOmegaInv_killProd_succ - theorem
MvFormalGroup.BigWittLaw.aeval_omegaInv_wittCoord - theorem
MvFormalGroup.BigWittLaw.evalOmegaInv_geomSeries - theorem
MvFormalGroup.BigWittLaw.geomSeries_zero - theorem
MvFormalGroup.BigWittLaw.evalOmegaInv_frobFactor - theorem
MvFormalGroup.BigWittLaw.aeval_omegaInv_frobPoly - def
MvFormalGroup.BigWittLaw.projPoly - theorem
MvFormalGroup.BigWittLaw.projPoly_zero - theorem
MvFormalGroup.BigWittLaw.isWeightedHomogeneous_projPoly - theorem
MvFormalGroup.BigWittLaw.constantCoeff_projPoly - theorem
MvFormalGroup.BigWittLaw.aeval_omegaInv_projPoly - def
MvFormalGroup.BigWittLaw.toFam - theorem
MvFormalGroup.BigWittLaw.coeff_toFam - theorem
MvFormalGroup.BigWittLaw.constantCoeff_toFam - theorem
MvFormalGroup.BigWittLaw.weight_eq_of_coeff_toFam_ne_zero - def
MvFormalGroup.BigWittLaw.wittCoordFam - def
MvFormalGroup.BigWittLaw.frobFam - def
MvFormalGroup.BigWittLaw.projFam - theorem
MvFormalGroup.BigWittLaw.wittCoordFam_apply - theorem
MvFormalGroup.BigWittLaw.frobFam_apply - theorem
MvFormalGroup.BigWittLaw.projFam_apply - theorem
MvFormalGroup.BigWittLaw.projFam_zero - theorem
MvFormalGroup.BigWittLaw.wittCoordFam_zero - theorem
MvFormalGroup.BigWittLaw.constantCoeff_wittCoordFam - theorem
MvFormalGroup.BigWittLaw.constantCoeff_frobFam - theorem
MvFormalGroup.BigWittLaw.constantCoeff_projFam - theorem
MvFormalGroup.BigWittLaw.hasSubst_wittCoordFam - theorem
MvFormalGroup.BigWittLaw.hasSubst_frobFam - theorem
MvFormalGroup.BigWittLaw.hasSubst_projFam
Source
import Mathlib import Definitions.Def_MvFormalGroup_BigWittLaw set_option autoImplicit false noncomputable section universe u namespace MvFormalGroup namespace BigWittLaw open MvPolynomial def genSeries : PowerSeries (MvPolynomial ℕ ℤ) := PowerSeries.mk fun n => Nat.casesOn n 1 fun m => X m @[simp] theorem coeff_genSeries_zero : PowerSeries.coeff 0 genSeries = 1 := by simp [genSeries, PowerSeries.coeff_mk] @[simp] theorem coeff_genSeries_succ (m : ℕ) : PowerSeries.coeff (m + 1) genSeries = X m := by simp [genSeries, PowerSeries.coeff_mk] @[simp] theorem constantCoeff_genSeries : PowerSeries.constantCoeff genSeries = 1 := by rw [← PowerSeries.coeff_zero_eq_constantCoeff_apply, coeff_genSeries_zero] def killProd : ℕ → PowerSeries (MvPolynomial ℕ ℤ) | 0 => genSeries | k + 1 => killProd k * (1 - PowerSeries.C (PowerSeries.coeff (k + 1) (killProd k)) * PowerSeries.X ^ (k + 1)) def wittCoord (k : ℕ) : MvPolynomial ℕ ℤ := PowerSeries.coeff (k + 1) (killProd k) theorem killProd_zero : killProd 0 = genSeries := rfl theorem killProd_succ (k : ℕ) : killProd (k + 1) = killProd k * (1 - PowerSeries.C (wittCoord k) * PowerSeries.X ^ (k + 1)) := rfl theorem wittCoord_eq (k : ℕ) : wittCoord k = PowerSeries.coeff (k + 1) (killProd k) := rfl @[simp] theorem wittCoord_zero : wittCoord 0 = X 0 := by rw [wittCoord_eq, killProd_zero, coeff_genSeries_succ] theorem killProd_eq_mul_prod (k : ℕ) : killProd k = genSeries * ∏ i ∈ Finset.range k, (1 - PowerSeries.C (wittCoord i) * PowerSeries.X ^ (i + 1)) := by induction k with | zero => simp [killProd_zero] | succ k ih => rw [killProd_succ, ih, Finset.prod_range_succ, mul_assoc] @[simp] theorem constantCoeff_killProd (k : ℕ) : PowerSeries.constantCoeff (killProd k) = 1 := by induction k with | zero => exact constantCoeff_genSeries | succ k ih => rw [killProd_succ, map_mul, ih, one_mul, map_sub, map_one, map_mul, map_pow, PowerSeries.constantCoeff_X, zero_pow (Nat.succ_ne_zero k), mul_zero, sub_zero] theorem coeff_mul_one_sub_C_mul_X_pow {A : Type*} [CommRing A] (P : PowerSeries A) (c : A) (k j : ℕ) : PowerSeries.coeff j (P * (1 - PowerSeries.C c * PowerSeries.X ^ (k + 1))) = PowerSeries.coeff j P - if k + 1 ≤ j then c * PowerSeries.coeff (j - (k + 1)) P else 0 := by rw [mul_sub, mul_one, map_sub] congr 1 split_ifs with h · obtain ⟨d, rfl⟩ := Nat.exists_eq_add_of_le h rw [show k + 1 + d = d + (k + 1) by omega, ← mul_assoc, mul_comm P, mul_assoc, PowerSeries.coeff_C_mul, PowerSeries.coeff_mul_X_pow, Nat.add_sub_cancel] · rw [not_le] at h rw [← mul_assoc, mul_comm P, mul_assoc, PowerSeries.coeff_C_mul, PowerSeries.coeff_mul, Finset.sum_eq_zero, mul_zero] rintro ⟨i, l⟩ hil rw [Finset.HasAntidiagonal.mem_antidiagonal] at hil rw [PowerSeries.coeff_X_pow, if_neg, mul_zero] omega theorem coeff_killProd_eq_zero {k j : ℕ} (hj : 1 ≤ j) (hjk : j ≤ k) : PowerSeries.coeff j (killProd k) = 0 := by induction k generalizing j with | zero => omega | succ k ih => rw [killProd_succ, coeff_mul_one_sub_C_mul_X_pow] rcases Nat.lt_or_ge j (k + 1) with h | h · rw [if_neg (by omega), sub_zero] exact ih hj (by omega) · have hjk' : j = k + 1 := le_antisymm hjk h subst hjk' rw [if_pos le_rfl, Nat.sub_self, PowerSeries.coeff_zero_eq_constantCoeff_apply, constantCoeff_killProd, mul_one, ← wittCoord_eq, sub_self] abbrev awt : ℕ → ℕ := fun m => m + 1 def IsIsobaric (n : ℕ) (P : PowerSeries (MvPolynomial ℕ ℤ)) : Prop := ∀ j, IsWeightedHomogeneous awt (PowerSeries.coeff j P) (n * j) theorem IsIsobaric.coeff {n : ℕ} {P : PowerSeries (MvPolynomial ℕ ℤ)} (h : IsIsobaric n P) (j : ℕ) : IsWeightedHomogeneous awt (PowerSeries.coeff j P) (n * j) := h j theorem isIsobaric_one (n : ℕ) : IsIsobaric n 1 := by intro j rw [PowerSeries.coeff_one] split_ifs with h · subst h; rw [mul_zero]; exact isWeightedHomogeneous_one ℤ awt · exact isWeightedHomogeneous_zero ℤ awt _ theorem IsIsobaric.mul {n : ℕ} {P Q : PowerSeries (MvPolynomial ℕ ℤ)} (hP : IsIsobaric n P) (hQ : IsIsobaric n Q) : IsIsobaric n (P * Q) := by intro j rw [PowerSeries.coeff_mul] refine IsWeightedHomogeneous.sum _ _ _ fun il hil => ?_ rw [Finset.HasAntidiagonal.mem_antidiagonal] at hil have h := (hP il.1).mul (hQ il.2) rwa [← mul_add, hil] at h theorem IsIsobaric.sub {n : ℕ} {P Q : PowerSeries (MvPolynomial ℕ ℤ)} (hP : IsIsobaric n P) (hQ : IsIsobaric n Q) : IsIsobaric n (P - Q) := by intro j rw [map_sub] exact (weightedHomogeneousSubmodule ℤ awt (n * j)).sub_mem (hP j) (hQ j) theorem IsIsobaric.prod {n : ℕ} {ι : Type*} (s : Finset ι) (P : ι → PowerSeries (MvPolynomial ℕ ℤ)) (h : ∀ i ∈ s, IsIsobaric n (P i)) : IsIsobaric n (∏ i ∈ s, P i) := by classical induction s using Finset.induction_on with | empty => rw [Finset.prod_empty]; exact isIsobaric_one n | insert i s hi ih => rw [Finset.prod_insert hi] exact (h i (Finset.mem_insert_self i s)).mul (ih fun l hl => h l (Finset.mem_insert_of_mem hl)) theorem IsIsobaric.pow {n : ℕ} {P : PowerSeries (MvPolynomial ℕ ℤ)} (hP : IsIsobaric n P) (e : ℕ) : IsIsobaric n (P ^ e) := by induction e with | zero => rw [pow_zero]; exact isIsobaric_one n | succ e ih => rw [pow_succ]; exact ih.mul hP theorem isIsobaric_C_mul_X_pow {n e : ℕ} {c : MvPolynomial ℕ ℤ} (hc : IsWeightedHomogeneous awt c (n * e)) : IsIsobaric n (PowerSeries.C c * PowerSeries.X ^ e) := by intro j rw [PowerSeries.coeff_C_mul_X_pow] split_ifs with h · subst h; exact hc · exact isWeightedHomogeneous_zero ℤ awt _ theorem isIsobaric_genSeries : IsIsobaric 1 genSeries := by intro j cases j with | zero => rw [coeff_genSeries_zero, mul_zero]; exact isWeightedHomogeneous_one ℤ awt | succ m => rw [coeff_genSeries_succ, one_mul]; exact isWeightedHomogeneous_X ℤ awt m theorem isIsobaric_killProd (k : ℕ) : IsIsobaric 1 (killProd k) := by induction k with | zero => exact isIsobaric_genSeries | succ k ih => rw [killProd_succ] refine ih.mul ((isIsobaric_one 1).sub (isIsobaric_C_mul_X_pow ?_)) exact ih (k + 1) theorem isWeightedHomogeneous_wittCoord (k : ℕ) : IsWeightedHomogeneous awt (wittCoord k) (k + 1) := by have h := isIsobaric_killProd k (k + 1) rwa [one_mul] at h theorem constantCoeff_wittCoord (k : ℕ) : constantCoeff (wittCoord k) = 0 := by by_contra h have h' : coeff (0 : ℕ →₀ ℕ) (wittCoord k) ≠ 0 := by rwa [← constantCoeff_eq] have hw := isWeightedHomogeneous_wittCoord k h' simp at hw def geomSeries {A : Type*} [CommRing A] (c : A) (e : ℕ) : PowerSeries A := PowerSeries.mk fun j => if e ∣ j then c ^ (j / e) else 0 theorem coeff_geomSeries {A : Type*} [CommRing A] (c : A) (e j : ℕ) : PowerSeries.coeff j (geomSeries c e) = if e ∣ j then c ^ (j / e) else 0 := PowerSeries.coeff_mk _ _ @[simp] theorem constantCoeff_geomSeries {A : Type*} [CommRing A] (c : A) (e : ℕ) : PowerSeries.constantCoeff (geomSeries c e) = 1 := by rw [← PowerSeries.coeff_zero_eq_constantCoeff_apply, coeff_geomSeries, if_pos (dvd_zero e), Nat.zero_div, pow_zero] theorem one_sub_C_mul_X_pow_mul_geomSeries {A : Type*} [CommRing A] (c : A) {e : ℕ} (he : e ≠ 0) : (1 - PowerSeries.C c * PowerSeries.X ^ e) * geomSeries c e = 1 := by obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero he ext j rw [mul_comm, coeff_mul_one_sub_C_mul_X_pow, coeff_geomSeries, PowerSeries.coeff_one] by_cases hj : k + 1 ≤ j · rw [if_pos hj, coeff_geomSeries] have hj0 : j ≠ 0 := by omega rw [if_neg hj0] by_cases hd : k + 1 ∣ j · have hd' : k + 1 ∣ j - (k + 1) := Nat.dvd_sub hd (dvd_refl _) rw [if_pos hd, if_pos hd'] obtain ⟨q, rfl⟩ := hd have hq : 1 ≤ q := by rcases q with _ | q · simp at hj · exact Nat.succ_pos q rw [show (k + 1) * q - (k + 1) = (k + 1) * (q - 1) by rw [Nat.mul_sub, mul_one], Nat.mul_div_cancel_left _ (Nat.succ_pos k), Nat.mul_div_cancel_left _ (Nat.succ_pos k), ← pow_succ', Nat.sub_add_cancel hq, sub_self] · have hd' : ¬ k + 1 ∣ j - (k + 1) := by intro h apply hd have := Nat.dvd_add h (dvd_refl (k + 1)) rwa [Nat.sub_add_cancel hj] at this rw [if_neg hd, if_neg hd', mul_zero, sub_zero] · rw [if_neg hj, sub_zero] by_cases hj0 : j = 0 · subst hj0 rw [if_pos (dvd_zero _), if_pos rfl, Nat.zero_div, pow_zero] · rw [if_neg hj0, if_neg] rintro ⟨q, rfl⟩ rcases q with _ | q · exact hj0 (mul_zero _) · apply hj calc k + 1 = (k + 1) * 1 := (mul_one _).symm _ ≤ (k + 1) * (q + 1) := Nat.mul_le_mul_left _ (by omega) def frobFactor (n k : ℕ) : PowerSeries (MvPolynomial ℕ ℤ) := geomSeries (wittCoord k ^ (n / Nat.gcd (k + 1) n)) ((k + 1) / Nat.gcd (k + 1) n) ^ Nat.gcd (k + 1) n def frobPoly (n m : ℕ) : MvPolynomial ℕ ℤ := PowerSeries.coeff (m + 1) (∏ k ∈ Finset.range (n * (m + 1)), frobFactor n k) @[simp] theorem constantCoeff_frobFactor (n k : ℕ) : PowerSeries.constantCoeff (frobFactor n k) = 1 := by rw [frobFactor, map_pow, constantCoeff_geomSeries, one_pow] theorem isIsobaric_geomSeries {n e : ℕ} {c : MvPolynomial ℕ ℤ} (hc : IsWeightedHomogeneous awt c (n * e)) : IsIsobaric n (geomSeries c e) := by intro j rw [coeff_geomSeries] split_ifs with h · obtain ⟨q, rfl⟩ := h rcases Nat.eq_zero_or_pos e with he | he · subst he rw [zero_mul, Nat.zero_div, pow_zero, mul_zero] exact isWeightedHomogeneous_one ℤ awt · rw [Nat.mul_div_cancel_left _ he] have h := hc.pow q rwa [smul_eq_mul, show q * (n * e) = n * (e * q) by ring] at h · exact isWeightedHomogeneous_zero ℤ awt _ theorem isIsobaric_frobFactor (n k : ℕ) : IsIsobaric n (frobFactor n k) := by refine (isIsobaric_geomSeries ?_).pow _ have h := (isWeightedHomogeneous_wittCoord k).pow (n / Nat.gcd (k + 1) n) rw [smul_eq_mul] at h convert h using 1 set g := Nat.gcd (k + 1) n with hg have hd : g ∣ k + 1 := Nat.gcd_dvd_left _ _ have hd' : g ∣ n := Nat.gcd_dvd_right _ _ calc n * ((k + 1) / g) = n / g * g * ((k + 1) / g) := by rw [Nat.div_mul_cancel hd'] _ = n / g * (g * ((k + 1) / g)) := by ring _ = n / g * (k + 1) := by rw [Nat.mul_div_cancel' hd] theorem isWeightedHomogeneous_frobPoly (n m : ℕ) : IsWeightedHomogeneous awt (frobPoly n m) (n * (m + 1)) := (IsIsobaric.prod _ _ fun k _ => isIsobaric_frobFactor n k) (m + 1) theorem constantCoeff_frobPoly {n : ℕ} (hn : n ≠ 0) (m : ℕ) : constantCoeff (frobPoly n m) = 0 := by by_contra h have h' : coeff (0 : ℕ →₀ ℕ) (frobPoly n m) ≠ 0 := by rwa [← constantCoeff_eq] have hw := isWeightedHomogeneous_frobPoly n m h' simp only [Finsupp.weight_apply, Finsupp.sum_zero_index] at hw exact absurd hw.symm (Nat.mul_ne_zero hn (Nat.succ_ne_zero m)) theorem frobPoly_zero_left (m : ℕ) : frobPoly 0 m = 0 := by rw [frobPoly, zero_mul, Finset.range_zero, Finset.prod_empty, PowerSeries.coeff_one, if_neg] exact Nat.succ_ne_zero m theorem genSeries_eq_killProd_mul_prod_geomSeries (K : ℕ) : genSeries = killProd K * ∏ k ∈ Finset.range K, geomSeries (wittCoord k) (k + 1) := by rw [killProd_eq_mul_prod, mul_assoc, ← Finset.prod_mul_distrib, Finset.prod_eq_one, mul_one] intro k _ exact one_sub_C_mul_X_pow_mul_geomSeries _ (Nat.succ_ne_zero k) theorem coeff_prod_geomSeries_wittCoord {K j : ℕ} (hj : j ≤ K) : PowerSeries.coeff j (∏ k ∈ Finset.range K, geomSeries (wittCoord k) (k + 1)) = PowerSeries.coeff j genSeries := by rw [genSeries_eq_killProd_mul_prod_geomSeries K, PowerSeries.coeff_mul, Finset.Nat.sum_antidiagonal_eq_sum_range_succ_mk, Finset.sum_range_succ', Nat.sub_zero, PowerSeries.coeff_zero_eq_constantCoeff_apply, constantCoeff_killProd, one_mul, Finset.sum_eq_zero, zero_add] intro i hi rw [coeff_killProd_eq_zero (Nat.succ_pos i) (by have := Finset.mem_range.mp hi; omega), zero_mul] theorem frobFactor_one (k : ℕ) : frobFactor 1 k = geomSeries (wittCoord k) (k + 1) := by rw [frobFactor, Nat.gcd_one_right, Nat.div_one, Nat.div_one, pow_one, pow_one] theorem frobPoly_one (m : ℕ) : frobPoly 1 m = X m := by rw [frobPoly, one_mul] simp only [frobFactor_one] rw [coeff_prod_geomSeries_wittCoord le_rfl, coeff_genSeries_succ] section OmegaInv variable {A : Type*} [CommRing A] (t : A) def evalOmegaInv : PowerSeries (MvPolynomial ℕ ℤ) →+* PowerSeries A := PowerSeries.map (MvPolynomial.aeval fun m : ℕ => t ^ (m + 1)).toRingHom theorem coeff_evalOmegaInv (P : PowerSeries (MvPolynomial ℕ ℤ)) (j : ℕ) : PowerSeries.coeff j (evalOmegaInv t P) = MvPolynomial.aeval (fun m : ℕ => t ^ (m + 1)) (PowerSeries.coeff j P) := PowerSeries.coeff_map _ _ _ theorem evalOmegaInv_genSeries : evalOmegaInv t genSeries = geomSeries t 1 := by ext j rw [coeff_evalOmegaInv, coeff_geomSeries, if_pos (one_dvd j), Nat.div_one] cases j with | zero => rw [coeff_genSeries_zero, map_one, pow_zero] | succ m => rw [coeff_genSeries_succ, MvPolynomial.aeval_X] theorem evalOmegaInv_C_mul_X_pow (c : MvPolynomial ℕ ℤ) (e : ℕ) : evalOmegaInv t (PowerSeries.C c * PowerSeries.X ^ e) = PowerSeries.C (MvPolynomial.aeval (fun m : ℕ => t ^ (m + 1)) c) * PowerSeries.X ^ e := by rw [evalOmegaInv, map_mul, map_pow] simp [PowerSeries.map_C, PowerSeries.map_X] theorem evalOmegaInv_killProd_succ (k : ℕ) : evalOmegaInv t (killProd (k + 1)) = 1 := by induction k with | zero => rw [killProd_succ, map_mul, killProd_zero, evalOmegaInv_genSeries, map_sub, map_one, evalOmegaInv_C_mul_X_pow, wittCoord_zero, MvPolynomial.aeval_X, zero_add, pow_one, mul_comm] exact one_sub_C_mul_X_pow_mul_geomSeries t one_ne_zero | succ k ih => rw [killProd_succ, map_mul, ih, one_mul, map_sub, map_one, evalOmegaInv_C_mul_X_pow, wittCoord_eq, ← coeff_evalOmegaInv, ih, PowerSeries.coeff_one, if_neg (Nat.succ_ne_zero _), map_zero, zero_mul, sub_zero] theorem aeval_omegaInv_wittCoord (k : ℕ) : MvPolynomial.aeval (fun m : ℕ => t ^ (m + 1)) (wittCoord k) = if k = 0 then t else 0 := by cases k with | zero => rw [wittCoord_zero, MvPolynomial.aeval_X, if_pos rfl, zero_add, pow_one] | succ k => rw [if_neg (Nat.succ_ne_zero k), wittCoord_eq, ← coeff_evalOmegaInv, evalOmegaInv_killProd_succ, PowerSeries.coeff_one, if_neg (Nat.succ_ne_zero _)] theorem evalOmegaInv_geomSeries (c : MvPolynomial ℕ ℤ) (e : ℕ) : evalOmegaInv t (geomSeries c e) = geomSeries (MvPolynomial.aeval (fun m : ℕ => t ^ (m + 1)) c) e := by ext j rw [coeff_evalOmegaInv, coeff_geomSeries, coeff_geomSeries] split_ifs · rw [map_pow] · rw [map_zero] omit t in theorem geomSeries_zero {e : ℕ} (he : e ≠ 0) : geomSeries (0 : A) e = 1 := by ext j rw [coeff_geomSeries, PowerSeries.coeff_one] by_cases hj : j = 0 · subst hj; rw [if_pos (dvd_zero e), if_pos rfl, Nat.zero_div, pow_zero] · rw [if_neg hj] split_ifs with h · rw [zero_pow] intro h0 rw [Nat.div_eq_zero_iff] at h0 rcases h0 with h0 | h0 · exact he h0 · exact hj (Nat.eq_zero_of_dvd_of_lt h h0) · rfl theorem evalOmegaInv_frobFactor {n : ℕ} (hn : n ≠ 0) (k : ℕ) : evalOmegaInv t (frobFactor n k) = if k = 0 then geomSeries (t ^ n) 1 else 1 := by rw [frobFactor, map_pow, evalOmegaInv_geomSeries, map_pow, aeval_omegaInv_wittCoord] have hg : 0 < Nat.gcd (k + 1) n := Nat.gcd_pos_of_pos_left _ (Nat.succ_pos k) split_ifs with hk · subst hk rw [zero_add, Nat.gcd_one_left, Nat.div_one, Nat.div_one, pow_one] · have h1 : n / Nat.gcd (k + 1) n ≠ 0 := Nat.div_ne_zero_iff.mpr ⟨hg.ne', Nat.gcd_le_right _ (Nat.pos_of_ne_zero hn)⟩ have h2 : (k + 1) / Nat.gcd (k + 1) n ≠ 0 := Nat.div_ne_zero_iff.mpr ⟨hg.ne', Nat.gcd_le_left _ (Nat.succ_pos k)⟩ rw [zero_pow h1, geomSeries_zero h2, one_pow] theorem aeval_omegaInv_frobPoly {n : ℕ} (hn : n ≠ 0) (m : ℕ) : MvPolynomial.aeval (fun m : ℕ => t ^ (m + 1)) (frobPoly n m) = t ^ (n * (m + 1)) := by rw [frobPoly, ← coeff_evalOmegaInv, map_prod] simp only [evalOmegaInv_frobFactor t hn] have h0 : (0 : ℕ) ∈ Finset.range (n * (m + 1)) := Finset.mem_range.mpr (Nat.mul_pos (Nat.pos_of_ne_zero hn) (Nat.succ_pos m)) rw [Finset.prod_ite, Finset.prod_const_one, mul_one, Finset.filter_eq' , if_pos h0, Finset.prod_singleton, coeff_geomSeries, if_pos (one_dvd _), Nat.div_one, ← pow_mul] end OmegaInv def projPoly (p k : ℕ) : MvPolynomial ℕ ℤ := wittCoord (p ^ k - 1) @[simp] theorem projPoly_zero (p : ℕ) : projPoly p 0 = X 0 := by rw [projPoly, pow_zero, Nat.sub_self, wittCoord_zero] theorem isWeightedHomogeneous_projPoly {p : ℕ} (hp : 0 < p) (k : ℕ) : IsWeightedHomogeneous awt (projPoly p k) (p ^ k) := by have h := isWeightedHomogeneous_wittCoord (p ^ k - 1) rwa [Nat.sub_add_cancel (Nat.one_le_pow k p hp)] at h theorem constantCoeff_projPoly (p k : ℕ) : constantCoeff (projPoly p k) = 0 := constantCoeff_wittCoord _ theorem aeval_omegaInv_projPoly {A : Type*} [CommRing A] (t : A) {p : ℕ} (hp : 2 ≤ p) (k : ℕ) : MvPolynomial.aeval (fun m : ℕ => t ^ (m + 1)) (projPoly p k) = if k = 0 then t else 0 := by rw [projPoly, aeval_omegaInv_wittCoord] cases k with | zero => rw [pow_zero, Nat.sub_self] | succ k => rw [if_neg (Nat.succ_ne_zero k), if_neg] have : p ^ (k + 1) ≥ 2 := le_trans hp (Nat.le_self_pow (Nat.succ_ne_zero k) p) omega section Families variable (R : Type u) [CommRing R] def toFam (P : MvPolynomial ℕ ℤ) : MvPowerSeries ℕ R := ↑(MvPolynomial.map (Int.castRingHom R) P) theorem coeff_toFam (P : MvPolynomial ℕ ℤ) (e : ℕ →₀ ℕ) : MvPowerSeries.coeff e (toFam R P) = ((coeff e P : ℤ) : R) := by rw [toFam, MvPolynomial.coeff_coe, coeff_map, eq_intCast] theorem constantCoeff_toFam {P : MvPolynomial ℕ ℤ} (hP : constantCoeff P = 0) : MvPowerSeries.constantCoeff (toFam R P) = 0 := by rw [← MvPowerSeries.coeff_zero_eq_constantCoeff_apply, coeff_toFam, ← constantCoeff_eq, hP, Int.cast_zero] theorem weight_eq_of_coeff_toFam_ne_zero {P : MvPolynomial ℕ ℤ} {w : ℕ} (hP : IsWeightedHomogeneous awt P w) {e : ℕ →₀ ℕ} (h : MvPowerSeries.coeff e (toFam R P) ≠ 0) : Finsupp.weight awt e = w := by rw [coeff_toFam] at h exact hP fun h0 => h (by rw [h0, Int.cast_zero]) def wittCoordFam : ℕ → MvPowerSeries ℕ R := fun k => toFam R (wittCoord k) def frobFam (n : ℕ) : ℕ → MvPowerSeries ℕ R := fun m => toFam R (frobPoly n m) def projFam (p : ℕ) : ℕ → MvPowerSeries ℕ R := fun k => toFam R (projPoly p k) @[simp] theorem wittCoordFam_apply (k : ℕ) : wittCoordFam R k = toFam R (wittCoord k) := rfl @[simp] theorem frobFam_apply (n m : ℕ) : frobFam R n m = toFam R (frobPoly n m) := rfl @[simp] theorem projFam_apply (p k : ℕ) : projFam R p k = toFam R (projPoly p k) := rfl theorem projFam_zero (p : ℕ) : projFam R p 0 = MvPowerSeries.X 0 := by rw [projFam_apply, projPoly_zero, toFam, map_X, MvPolynomial.coe_X] theorem wittCoordFam_zero : wittCoordFam R 0 = MvPowerSeries.X 0 := by rw [wittCoordFam_apply, wittCoord_zero, toFam, map_X, MvPolynomial.coe_X] theorem constantCoeff_wittCoordFam (k : ℕ) : MvPowerSeries.constantCoeff (wittCoordFam R k) = 0 := constantCoeff_toFam R (constantCoeff_wittCoord k) theorem constantCoeff_frobFam {n : ℕ} (hn : n ≠ 0) (m : ℕ) : MvPowerSeries.constantCoeff (frobFam R n m) = 0 := constantCoeff_toFam R (constantCoeff_frobPoly hn m) theorem constantCoeff_projFam (p k : ℕ) : MvPowerSeries.constantCoeff (projFam R p k) = 0 := constantCoeff_toFam R (constantCoeff_projPoly p k) theorem hasSubst_wittCoordFam : MvPowerSeries.HasSubst (wittCoordFam R) := by refine ⟨fun k => by rw [constantCoeff_wittCoordFam]; exact IsNilpotent.zero, fun e => ?_⟩ refine (Set.finite_le_nat (Finsupp.weight awt e)).subset fun k hk => ?_ have hw := weight_eq_of_coeff_toFam_ne_zero R (isWeightedHomogeneous_wittCoord k) hk show k ≤ Finsupp.weight awt e omega theorem hasSubst_frobFam (n : ℕ) : MvPowerSeries.HasSubst (frobFam R n) := by rcases Nat.eq_zero_or_pos n with hn | hn · subst hn have h0 : frobFam R 0 = 0 := by funext m rw [frobFam_apply, frobPoly_zero_left, toFam, map_zero, MvPolynomial.coe_zero] rfl rw [h0] exact MvPowerSeries.HasSubst.zero refine ⟨fun m => by rw [constantCoeff_frobFam R hn.ne']; exact IsNilpotent.zero, fun e => ?_⟩ refine (Set.finite_le_nat (Finsupp.weight awt e)).subset fun m hm => ?_ have hw := weight_eq_of_coeff_toFam_ne_zero R (isWeightedHomogeneous_frobPoly n m) hm show m ≤ Finsupp.weight awt e rw [hw] calc m ≤ m + 1 := Nat.le_succ m _ = 1 * (m + 1) := (one_mul _).symm _ ≤ n * (m + 1) := Nat.mul_le_mul_right _ hn theorem hasSubst_projFam {p : ℕ} (hp : 2 ≤ p) : MvPowerSeries.HasSubst (projFam R p) := by refine ⟨fun k => by rw [constantCoeff_projFam]; exact IsNilpotent.zero, fun e => ?_⟩ refine (Set.finite_lt_nat (Finsupp.weight awt e)).subset fun k hk => ?_ have hw := weight_eq_of_coeff_toFam_ne_zero R (isWeightedHomogeneous_projPoly (by omega) k) hk show k < Finsupp.weight awt e rw [hw] exact Nat.lt_pow_self (by omega) end Families end BigWittLaw end MvFormalGroup end
Statements phrased using this module (10)
- Low-weight coefficients vanish for big-Witt homomorphisms
MvFormalGroup.BigWittLaw.coeff_eq_zero_of_coeff_subst_pow_eq_zero0 below · depth 36 - Cartier's first theorem, ω-curve form
MvFormalGroup.BigWittLaw.exists_hom_subst_pow_eq1 below · depth 36 - Frobenius family mathbf Fₙ is additive for the big Witt law
MvFormalGroup.BigWittLaw.subst_addFam_frobFam0 below · depth 36 - Additivity of `projFam` and splitting of Artin–Hasse
MvFormalGroup.BigWittLaw.subst_addFam_projFam_and_subst_artinHasse_projFam2 below · depth 36 - Artin–Hasse coordinates intertwine the big Witt and Witt Frobenii
MvFormalGroup.BigWittLaw.subst_artinHasse_frobFam1 below · depth 36 - Artin–Hasse projector kills non-p-power Frobenii, commutes with mathbf Fₚ
MvFormalGroup.BigWittLaw.subst_artinHasse_projFam_frobFam1 below · depth 36 - Difference of two big Witt homomorphisms agreeing to order n
MvFormalGroup.BigWittLaw.subst_elim_negSeries_hom_and_coeff_eq_zero0 below · depth 36 - Frobenius mathbf Fₙ of the big Witt law on ω-curves
MvFormalGroup.BigWittLaw.subst_pow_subst_frobFam0 below · depth 36 - The ω-curve of f∘π is the standard curve of f
MvFormalGroup.BigWittLaw.subst_pow_subst_projFam0 below · depth 36 - Weight-adic convergence of sums in the Cartier module
MvFormalGroup.CartierModule.exists_forall_coeff_sub_sum_eq_zero0 below · depth 36