Definitions/Def_CerednikDrinfeld_LubinTateModule.lean
Lubin–Tate series, the formal group Σ, and its reduction
Fix a prime p. The first part works over W(k) for a finite field k of characteristic p, writes q=\#k and puts f(X_s)=pX_s+X_s^{q}: fvec is the family s\mapsto C(p)X_s+X_s^{q} indexed by a variable set \tau, the predicate Comm on \varphi\in W(k)[[X_\tau]] asserts p\varphi+\varphi^{q}=\varphi\bigl(f(X_s)\bigr)_{s} (substitution of fvec into \varphi), and defect is the difference of the two sides. The main result existsUnique_series states that for finite \tau and any prescribed family c\colon\tau\to W(k) there is exactly one \varphi with zero constant term, \operatorname{coeff}_{X_s}\varphi=c_s for all s, and satisfying that commutation relation. Uniqueness (eq_of_comm) compares coefficients degree by degree using that p and 1-p^{n+1} are non-zero, the latter a unit in W(k); existence builds successive approximations approx, correcting in each total degree by a term obtained from defect, which is divisible by p coefficientwise because it vanishes modulo p, and ltSeries assembles the limit.
The second part specialises k=\mathbb{F}_{p^{2}}, so q=p^{2}, over the ring Zp2 p, here the Witt vectors of GaloisField p 2, and names the chosen solution lt. From it: sigmaSeries is the two-variable series with both linear coefficients 1, packaged as a one-dimensional formal group law sigma (an MvFormalGroup whose associativity and normalisation are structure fields), commutative; and act₁ a is the one-variable series with linear coefficient a, with [1]=X, [0]=0, [ab]=[a]\circ[b], [a+b]=\Sigma([a],[b]) and [p]=pX+X^{p^{2}}. Coefficientwise Witt Frobenius fixes sigmaSeries and sends act₁ a to act₁ (σa). Given a commutative ring B and j\colon Zp2 p \to B, sigmaBar j is the image formal group, rho j the ring homomorphism sending a to the endomorphism with series j([a]); for B of characteristic p, phi j is the endomorphism X_0^{p}, and \varphi\rho(a)=\rho(\sigma a)\varphi, \varphi^{2}=\rho(p).
Relation to Mathlib
The multivariate formal-group structures used (MvFormalGroup, its homomorphisms and endomorphism ring) are the project's own, from the imported definition modules; Witt vectors, GaloisField and substitution for multivariate power series are Mathlib's.
Where it is used
These series and the pair (\rho,\varphi) are the one-dimensional input for Drinfeld's special formal \mathcal{O}_D-modules, the objects behind the p-adic uniformisation of Shimura curves; within the project they serve the Čerednik–Drinfeld material supporting the level-lowering step.
References
- J. Lubin and J. Tate, Formal complex multiplication in local fields, Annals of Mathematics 81 (1965), 380–387
- V. G. Drinfeld, Coverings of p-adic symmetric domains, Functional Analysis and its Applications 10 (1976), 107–115
- J.-F. Boutot and H. Carayol, Uniformisation p-adique des courbes de Shimura: les théorèmes de Čerednik et de Drinfeld, Astérisque 196–197 (1991), 45–158
References are suggested automatically and have not been individually verified.
English text generated automatically from the Lean source; the Lean statement is authoritative.
- 1,125 lines
- 122 declarations
- used in the statements of 1 theorems and imported by 2 proofs
- imports 2 definition modules
Source file: Definitions/Def_CerednikDrinfeld_LubinTateModule.lean
Imported by
Declarations
- theorem
CerednikDrinfeld.LubinTateLemma.two_le_card - theorem
CerednikDrinfeld.LubinTateLemma.card_ne_zero - theorem
CerednikDrinfeld.LubinTateLemma.constantCoeff_natCast_p - theorem
CerednikDrinfeld.LubinTateLemma.p_ne_zero' - theorem
CerednikDrinfeld.LubinTateLemma.isUnit_one_sub_pow - theorem
CerednikDrinfeld.LubinTateLemma.one_sub_pow_ne_zero - theorem
CerednikDrinfeld.LubinTateLemma.exists_eq_p_mul_of_coeff_zero - def
CerednikDrinfeld.LubinTateLemma.fvec - def
CerednikDrinfeld.LubinTateLemma.Comm - def
CerednikDrinfeld.LubinTateLemma.defect - theorem
CerednikDrinfeld.LubinTateLemma.constantCoeff_fvec - theorem
CerednikDrinfeld.LubinTateLemma.hasSubst_fvec - theorem
CerednikDrinfeld.LubinTateLemma.coeff_single_X_pow_card - theorem
CerednikDrinfeld.LubinTateLemma.coeff_single_fvec - theorem
CerednikDrinfeld.LubinTateLemma.comm_X - theorem
CerednikDrinfeld.LubinTateLemma.constantCoeff_C_mul_X - theorem
CerednikDrinfeld.LubinTateLemma.comm_subst - theorem
CerednikDrinfeld.LubinTateLemma.finsuppProd_C_mul_X_pow - theorem
CerednikDrinfeld.LubinTateLemma.coeff_finsuppProd_fvec_pow - theorem
CerednikDrinfeld.LubinTateLemma.coeff_subst_fvec - theorem
CerednikDrinfeld.LubinTateLemma.pow_card_eq_subst_X_pow - theorem
CerednikDrinfeld.LubinTateLemma.map_defect_eq_zero - theorem
CerednikDrinfeld.LubinTateLemma.exists_coeff_defect_eq_mul - theorem
CerednikDrinfeld.LubinTateLemma.eq_zero_or_single_of_degree_le_one - theorem
CerednikDrinfeld.LubinTateLemma.eq_of_comm - def
CerednikDrinfeld.LubinTateLemma.pdiv - theorem
CerednikDrinfeld.LubinTateLemma.pdiv_spec - def
CerednikDrinfeld.LubinTateLemma.corr - theorem
CerednikDrinfeld.LubinTateLemma.coeff_corr - theorem
CerednikDrinfeld.LubinTateLemma.coeff_corr_of_ne - def
CerednikDrinfeld.LubinTateLemma.approx - theorem
CerednikDrinfeld.LubinTateLemma.approx_succ - theorem
CerednikDrinfeld.LubinTateLemma.coeff_approx_zero - theorem
CerednikDrinfeld.LubinTateLemma.coeff_approx_zero_of_degree_ne_one - theorem
CerednikDrinfeld.LubinTateLemma.coeff_single_approx_zero - theorem
CerednikDrinfeld.LubinTateLemma.coeff_approx_of_le - theorem
CerednikDrinfeld.LubinTateLemma.constantCoeff_approx - theorem
CerednikDrinfeld.LubinTateLemma.coeff_single_approx - theorem
CerednikDrinfeld.LubinTateLemma.coeff_defect_approx - def
CerednikDrinfeld.LubinTateLemma.ltSeries - theorem
CerednikDrinfeld.LubinTateLemma.coeff_ltSeries - theorem
CerednikDrinfeld.LubinTateLemma.coeff_ltSeries_of_le - theorem
CerednikDrinfeld.LubinTateLemma.constantCoeff_ltSeries - theorem
CerednikDrinfeld.LubinTateLemma.coeff_single_ltSeries - theorem
CerednikDrinfeld.LubinTateLemma.coeff_defect_congr - theorem
CerednikDrinfeld.LubinTateLemma.comm_ltSeries - theorem
CerednikDrinfeld.LubinTateLemma.existsUnique_series - instance
CerednikDrinfeld.LubinTate.instFintypeGaloisFieldTwo - theorem
CerednikDrinfeld.LubinTate.card_GF - theorem
CerednikDrinfeld.LubinTate.two_le_card - theorem
CerednikDrinfeld.LubinTate.frobenius_frobenius - theorem
CerednikDrinfeld.LubinTate.exists_pow_ne - theorem
CerednikDrinfeld.LubinTate.exists_isUnit_frobenius_sub - def
CerednikDrinfeld.LubinTate.fvec - def
CerednikDrinfeld.LubinTate.Comm - theorem
CerednikDrinfeld.LubinTate.lt_existsUnique - def
CerednikDrinfeld.LubinTate.lt - theorem
CerednikDrinfeld.LubinTate.lt_spec - theorem
CerednikDrinfeld.LubinTate.constantCoeff_lt - theorem
CerednikDrinfeld.LubinTate.coeff_single_lt - theorem
CerednikDrinfeld.LubinTate.comm_lt - theorem
CerednikDrinfeld.LubinTate.eq_of_comm - theorem
CerednikDrinfeld.LubinTate.constantCoeff_fvec - theorem
CerednikDrinfeld.LubinTate.hasSubst_fvec - theorem
CerednikDrinfeld.LubinTate.coeff_single_X_pow_card - theorem
CerednikDrinfeld.LubinTate.coeff_single_fvec - theorem
CerednikDrinfeld.LubinTate.comm_X - theorem
CerednikDrinfeld.LubinTate.comm_fvec - theorem
CerednikDrinfeld.LubinTate.comm_subst - theorem
CerednikDrinfeld.LubinTate.comm_subst_X - theorem
CerednikDrinfeld.LubinTate.constantCoeff_subst_of - theorem
CerednikDrinfeld.LubinTate.coeff_single_subst_lt - theorem
CerednikDrinfeld.LubinTate.map_frobenius_fvec - theorem
CerednikDrinfeld.LubinTate.comm_map_frobenius - theorem
CerednikDrinfeld.LubinTate.map_frobenius_lt - def
CerednikDrinfeld.LubinTate.sigmaSeries - def
CerednikDrinfeld.LubinTate.act₁ - theorem
CerednikDrinfeld.LubinTate.constantCoeff_sigmaSeries - theorem
CerednikDrinfeld.LubinTate.comm_sigmaSeries - theorem
CerednikDrinfeld.LubinTate.coeff_single_sigmaSeries - theorem
CerednikDrinfeld.LubinTate.coeff_single_subst_sigmaSeries - theorem
CerednikDrinfeld.LubinTate.constantCoeff_act₁ - theorem
CerednikDrinfeld.LubinTate.comm_act₁ - theorem
CerednikDrinfeld.LubinTate.coeff_single_act₁ - theorem
CerednikDrinfeld.LubinTate.coeff_single_subst_act₁ - theorem
CerednikDrinfeld.LubinTate.hasSubst_fin1 - def
CerednikDrinfeld.LubinTate.sigma - theorem
CerednikDrinfeld.LubinTate.sigma_toPowerSeries - instance
CerednikDrinfeld.LubinTate.sigma_isComm - theorem
CerednikDrinfeld.LubinTate.constantCoeff_homFamily₁ - theorem
CerednikDrinfeld.LubinTate.subst_sigma_eq_of_comm - theorem
CerednikDrinfeld.LubinTate.subst_sigma_act₁ - theorem
CerednikDrinfeld.LubinTate.act₁_one - theorem
CerednikDrinfeld.LubinTate.act₁_zero - theorem
CerednikDrinfeld.LubinTate.act₁_mul - theorem
CerednikDrinfeld.LubinTate.act₁_add - theorem
CerednikDrinfeld.LubinTate.act₁_natCast_p - theorem
CerednikDrinfeld.LubinTate.map_frobenius_sigmaSeries - theorem
CerednikDrinfeld.LubinTate.map_frobenius_act₁ - instance
CerednikDrinfeld.LubinTate.instIsCommMap - theorem
CerednikDrinfeld.LubinTate.map_homIdentity₁ - def
CerednikDrinfeld.LubinTate.sigmaBar - theorem
CerednikDrinfeld.LubinTate.sigmaBar_toPowerSeries - instance
CerednikDrinfeld.LubinTate.sigmaBar_isComm - def
CerednikDrinfeld.LubinTate.rhoEnd - theorem
CerednikDrinfeld.LubinTate.rhoEnd_toPowerSeries - theorem
CerednikDrinfeld.LubinTate.toPowerSeries_fin1 - def
CerednikDrinfeld.LubinTate.rho - theorem
CerednikDrinfeld.LubinTate.rho_toPowerSeries - theorem
CerednikDrinfeld.LubinTate.coeff_single_rho - theorem
CerednikDrinfeld.LubinTate.rho_p_toPowerSeries - theorem
CerednikDrinfeld.LubinTate.j_eq_teichmuller - theorem
CerednikDrinfeld.LubinTate.j_frobenius - theorem
CerednikDrinfeld.LubinTate.map_frobenius_map_j - theorem
CerednikDrinfeld.LubinTate.hp0 - theorem
CerednikDrinfeld.LubinTate.pow_p_eq_expand_map - theorem
CerednikDrinfeld.LubinTate.sigmaBar_pow_p - def
CerednikDrinfeld.LubinTate.phi - theorem
CerednikDrinfeld.LubinTate.phi_toPowerSeries - theorem
CerednikDrinfeld.LubinTate.phi_mul_rho - theorem
CerednikDrinfeld.LubinTate.phi_mul_phi - theorem
CerednikDrinfeld.LubinTate.rho_mul_comm
Source
import Mathlib import Definitions.Def_MvFormalGroup_NegV2 import Definitions.Def_CerednikDrinfeld_SpecialFormalModule set_option autoImplicit false set_option linter.unusedSectionVars false noncomputable section open MvPowerSeries namespace CerednikDrinfeld.LubinTateLemma variable {p : ℕ} [Fact p.Prime] {k : Type*} [Field k] [Fintype k] [CharP k p] theorem two_le_card : 2 ≤ Fintype.card k := Fintype.one_lt_card theorem card_ne_zero : Fintype.card k ≠ 0 := by have := two_le_card (k := k); omega theorem constantCoeff_natCast_p : WittVector.constantCoeff (p : WittVector p k) = 0 := by rw [WittVector.constantCoeff_apply, WittVector.coeff_p_zero] theorem p_ne_zero' : (p : WittVector p k) ≠ 0 := WittVector.p_nonzero p k theorem isUnit_one_sub_pow (r : ℕ) : IsUnit (1 - (p : WittVector p k) ^ (r + 1)) := by apply WittVector.isUnit_of_coeff_zero_ne_zero rw [← WittVector.constantCoeff_apply, map_sub, map_one, map_pow, constantCoeff_natCast_p, zero_pow (Nat.succ_ne_zero r), sub_zero] exact one_ne_zero theorem one_sub_pow_ne_zero (r : ℕ) : (1 - (p : WittVector p k) ^ (r + 1)) ≠ 0 := (isUnit_one_sub_pow r).ne_zero theorem exists_eq_p_mul_of_coeff_zero (x : WittVector p k) (hx : x.coeff 0 = 0) : ∃ y : WittVector p k, x = (p : WittVector p k) * y := by have h1 : x = WittVector.verschiebung (x.shift 1) := by have := WittVector.eq_iterate_verschiebung (x := x) (n := 1) (by intro i hi have hi0 : i = 0 := by omega subst hi0 exact hx) simpa using this obtain ⟨y, hy⟩ := (WittVector.frobenius_bijective p k).2 (x.shift 1) refine ⟨y, ?_⟩ rw [h1, ← hy, WittVector.verschiebung_frobenius, mul_comm] variable (p k) def fvec (τ : Type*) : τ → MvPowerSeries τ (WittVector p k) := fun s => C (p : WittVector p k) * X s + X s ^ Fintype.card k def Comm {τ : Type*} (φ : MvPowerSeries τ (WittVector p k)) : Prop := C (p : WittVector p k) * φ + φ ^ Fintype.card k = subst (fvec p k τ) φ def defect {τ : Type*} (θ : MvPowerSeries τ (WittVector p k)) : MvPowerSeries τ (WittVector p k) := C (p : WittVector p k) * θ + θ ^ Fintype.card k - subst (fvec p k τ) θ variable {p k} section Family variable {τ : Type*} theorem constantCoeff_fvec (s : τ) : constantCoeff (fvec p k τ s) = 0 := by simp only [fvec, map_add, map_mul, constantCoeff_C, constantCoeff_X, mul_zero, map_pow, zero_pow (card_ne_zero (k := k)), add_zero] theorem hasSubst_fvec [Finite τ] : HasSubst (fvec p k τ) := hasSubst_of_constantCoeff_zero constantCoeff_fvec theorem coeff_single_X_pow_card [DecidableEq τ] (s t : τ) : coeff (Finsupp.single t 1) ((X s : MvPowerSeries τ (WittVector p k)) ^ Fintype.card k) = 0 := by rw [coeff_X_pow, if_neg] intro h have := congrArg (fun d => d t) h simp only [Finsupp.single_eq_same] at this by_cases hts : t = s · subst hts rw [Finsupp.single_eq_same] at this have := two_le_card (k := k) omega · rw [Finsupp.single_eq_of_ne hts] at this exact one_ne_zero this theorem coeff_single_fvec [DecidableEq τ] (s t : τ) : coeff (Finsupp.single t 1) (fvec p k τ s) = if t = s then (p : WittVector p k) else 0 := by rw [fvec, map_add, coeff_C_mul, coeff_index_single_X, coeff_single_X_pow_card, add_zero] split_ifs <;> simp theorem comm_X [Finite τ] (s : τ) : Comm p k (X s : MvPowerSeries τ (WittVector p k)) := by unfold Comm rw [subst_X hasSubst_fvec] rfl theorem constantCoeff_C_mul_X (s : τ) : constantCoeff (C (p : WittVector p k) * (X s : MvPowerSeries τ (WittVector p k))) = 0 := by rw [map_mul, constantCoeff_X, mul_zero] theorem comm_subst {σ : Type*} [Finite σ] [Finite τ] {φ : MvPowerSeries σ (WittVector p k)} (hφ : Comm p k φ) {a : σ → MvPowerSeries τ (WittVector p k)} (ha0 : ∀ s, constantCoeff (a s) = 0) (ha : ∀ s, Comm p k (a s)) : Comm p k (subst a φ) := by have hsa : HasSubst a := hasSubst_of_constantCoeff_zero ha0 unfold Comm at * calc C (p : WittVector p k) * subst a φ + subst a φ ^ Fintype.card k = subst a (C (p : WittVector p k) * φ + φ ^ Fintype.card k) := by rw [subst_add hsa, subst_mul hsa, subst_pow hsa, subst_C] _ = subst a (subst (fvec p k σ) φ) := by rw [hφ] _ = subst (fun s => subst a (fvec p k σ s)) φ := subst_comp_subst_apply hasSubst_fvec hsa φ _ = subst (fun s => subst (fvec p k τ) (a s)) φ := by congr 1 funext s show subst a (C (p : WittVector p k) * X s + X s ^ Fintype.card k) = _ rw [subst_add hsa, subst_mul hsa, subst_C, subst_pow hsa, subst_X hsa] exact ha s _ = subst (fvec p k τ) (subst a φ) := (subst_comp_subst_apply hsa hasSubst_fvec φ).symm end Family section Leading variable {τ : Type*} [Fintype τ] [DecidableEq τ] theorem finsuppProd_C_mul_X_pow (m : τ →₀ ℕ) : (m.prod fun s e => (C (p : WittVector p k) * (X s : MvPowerSeries τ (WittVector p k))) ^ e) = C ((p : WittVector p k) ^ m.degree) * monomial m 1 := by have h : (fun s e => (C (p : WittVector p k) * (X s : MvPowerSeries τ (WittVector p k))) ^ e) = fun s e => C ((p : WittVector p k) ^ e) * X s ^ e := by funext s e rw [mul_pow, map_pow] rw [h, Finsupp.prod_mul, ← monomial_one_eq, ← map_finsuppProd] congr 2 rw [Finsupp.degree_apply, Finsupp.prod, Finset.prod_pow_eq_pow_sum] theorem coeff_finsuppProd_fvec_pow {d m : τ →₀ ℕ} (hdm : d.degree = m.degree) : coeff d (m.prod fun s e => (fvec p k τ s) ^ e) = if d = m then (p : WittVector p k) ^ m.degree else 0 := by have hcc : ∀ s, ∀ e : τ →₀ ℕ, e.degree < 2 → coeff e (fvec p k τ s) = coeff e (C (p : WittVector p k) * X s) := by intro s e he rw [fvec, map_add, add_eq_left, coeff_X_pow, if_neg] intro h subst h rw [Finsupp.degree_single] at he have := two_le_card (k := k) omega have key := MvFormalGroup.coeff_finsuppProd_pow_sub_congr (N := 2) (by norm_num) (c := fvec p k τ) (c' := fun s => C (p : WittVector p k) * X s) constantCoeff_fvec constantCoeff_C_mul_X hcc (m := m) (d := d) (by omega) rw [key, finsuppProd_C_mul_X_pow, coeff_C_mul, coeff_monomial] split_ifs <;> simp theorem coeff_subst_fvec {θ : MvPowerSeries τ (WittVector p k)} {n : ℕ} (hθ : ∀ e : τ →₀ ℕ, e.degree < n → coeff e θ = 0) {d : τ →₀ ℕ} (hd : d.degree ≤ n) : coeff d (subst (fvec p k τ) θ) = (p : WittVector p k) ^ d.degree * coeff d θ := by rw [coeff_subst hasSubst_fvec, finsum_eq_single _ d] · rw [coeff_finsuppProd_fvec_pow rfl, if_pos rfl, smul_eq_mul, mul_comm] · intro m hm rcases lt_trichotomy m.degree d.degree with hlt | heq | hgt · rw [hθ m (by omega), zero_smul] · rw [coeff_finsuppProd_fvec_pow heq.symm, if_neg (Ne.symm hm), smul_zero] · rw [MvFormalGroup.coeff_finsuppProd_pow_eq_zero_of_degree_lt constantCoeff_fvec hgt, smul_zero] end Leading section Divisible variable {τ : Type*} include p in theorem pow_card_eq_subst_X_pow (g : MvPowerSeries τ k) : g ^ Fintype.card k = subst (fun s : τ => (X s : MvPowerSeries τ k) ^ Fintype.card k) g := by obtain ⟨n, hp, hn⟩ := FiniteField.card k p have hp0 : p ≠ 0 := hp.ne_zero rw [hn, ← map_iterateFrobenius_expand p hp0 g n, iterateFrobenius_eq_pow, FiniteField.frobenius_pow hn, RingHom.one_def, MvPowerSeries.map_id, RingHom.id_apply] unfold MvPowerSeries.expand rw [substAlgHom_apply] theorem map_defect_eq_zero [Finite τ] (θ : MvPowerSeries τ (WittVector p k)) : MvPowerSeries.map (WittVector.constantCoeff : WittVector p k →+* k) (defect p k θ) = 0 := by have hf : HasSubst (fvec p k τ) := hasSubst_fvec rw [defect, map_sub, map_add, map_mul, map_pow, map_C, constantCoeff_natCast_p, map_zero, zero_mul, zero_add, map_subst hf, sub_eq_zero] have hfam : (fun s => MvPowerSeries.map (WittVector.constantCoeff : WittVector p k →+* k) (fvec p k τ s)) = fun s : τ => (X s : MvPowerSeries τ k) ^ Fintype.card k := by funext s simp only [fvec, map_add, map_mul, map_C, constantCoeff_natCast_p, map_zero, zero_mul, zero_add, map_pow, map_X] rw [hfam] exact pow_card_eq_subst_X_pow _ theorem exists_coeff_defect_eq_mul [Finite τ] (θ : MvPowerSeries τ (WittVector p k)) (e : τ →₀ ℕ) : ∃ y : WittVector p k, coeff e (defect p k θ) = (p : WittVector p k) * y := by apply exists_eq_p_mul_of_coeff_zero rw [← WittVector.constantCoeff_apply, ← MvPowerSeries.coeff_map, map_defect_eq_zero, map_zero] end Divisible section Unique variable {τ : Type*} [Fintype τ] [DecidableEq τ] theorem eq_zero_or_single_of_degree_le_one {d : τ →₀ ℕ} (hd : d.degree ≤ 1) : d = 0 ∨ ∃ s, d = Finsupp.single s 1 := by rcases Nat.lt_or_ge d.degree 1 with h0 | h1 · left exact (Finsupp.degree_eq_zero_iff d).mp (by omega) · right have hdeg : d.degree = 1 := le_antisymm hd h1 have hmem : d ∈ {d' : τ →₀ ℕ | d'.degree = 1} := hdeg rw [← Finsupp.range_single_one] at hmem obtain ⟨s, hs⟩ := hmem exact ⟨s, hs.symm⟩ theorem eq_of_comm {φ ψ : MvPowerSeries τ (WittVector p k)} (hφ0 : constantCoeff φ = 0) (hψ0 : constantCoeff ψ = 0) (h1 : ∀ s, coeff (Finsupp.single s 1) φ = coeff (Finsupp.single s 1) ψ) (hφ : Comm p k φ) (hψ : Comm p k ψ) : φ = ψ := by suffices key : ∀ n : ℕ, ∀ d : τ →₀ ℕ, d.degree ≤ n + 1 → coeff d φ = coeff d ψ from MvPowerSeries.ext fun d => key d.degree d (Nat.le_succ _) intro n induction n with | zero => intro d hd rcases eq_zero_or_single_of_degree_le_one hd with rfl | ⟨s, rfl⟩ · rw [coeff_zero_eq_constantCoeff_apply, coeff_zero_eq_constantCoeff_apply, hφ0, hψ0] · exact h1 s | succ n IH => intro d hd by_cases hlt : d.degree ≤ n + 1 · exact IH d hlt have hdeg : d.degree = n + 2 := by omega have hf : HasSubst (fvec p k τ) := hasSubst_fvec have hδ : ∀ e : τ →₀ ℕ, e.degree < n + 2 → coeff e (φ - ψ) = 0 := by intro e he rw [map_sub, IH e (by omega), sub_self] have hpow : coeff d (φ ^ Fintype.card k) = coeff d (ψ ^ Fintype.card k) := MvFormalGroup.coeff_pow_sub_congr (N := n + 2) (by omega) hφ0 hψ0 (fun e he => IH e (by omega)) (by have := two_le_card (k := k); omega) have hsub : coeff d (subst (fvec p k τ) φ) - coeff d (subst (fvec p k τ) ψ) = (p : WittVector p k) ^ (n + 2) * coeff d (φ - ψ) := by rw [← map_sub, ← subst_sub hf, coeff_subst_fvec hδ (le_of_eq hdeg), hdeg] have eφ := congrArg (coeff d) hφ have eψ := congrArg (coeff d) hψ simp only [map_add, coeff_C_mul] at eφ eψ have hc : (p : WittVector p k) * (1 - (p : WittVector p k) ^ (n + 1)) * coeff d (φ - ψ) = 0 := by have : (p : WittVector p k) * coeff d (φ - ψ) = (p : WittVector p k) ^ (n + 2) * coeff d (φ - ψ) := by rw [← hsub, ← eφ, ← eψ, hpow, map_sub] ring linear_combination this rcases mul_eq_zero.mp hc with h | h · rcases mul_eq_zero.mp h with h' | h' · exact absurd h' p_ne_zero' · exact absurd h' (one_sub_pow_ne_zero n) · rwa [map_sub, sub_eq_zero] at h end Unique section Exists variable {τ : Type*} [Fintype τ] [DecidableEq τ] open scoped Classical in def pdiv (x : WittVector p k) : WittVector p k := if h : ∃ y : WittVector p k, x = (p : WittVector p k) * y then h.choose else 0 theorem pdiv_spec {x : WittVector p k} (h : ∃ y : WittVector p k, x = (p : WittVector p k) * y) : x = (p : WittVector p k) * pdiv x := by rw [pdiv, dif_pos h] exact h.choose_spec def corr (θ : MvPowerSeries τ (WittVector p k)) (n : ℕ) : MvPowerSeries τ (WittVector p k) := fun d => if d.degree = n + 2 then -(((isUnit_one_sub_pow (p := p) (k := k) n).unit⁻¹ : (WittVector p k)ˣ) : WittVector p k) * pdiv (coeff d (defect p k θ)) else 0 theorem coeff_corr (θ : MvPowerSeries τ (WittVector p k)) (n : ℕ) (d : τ →₀ ℕ) : coeff d (corr θ n) = if d.degree = n + 2 then -(((isUnit_one_sub_pow (p := p) (k := k) n).unit⁻¹ : (WittVector p k)ˣ) : WittVector p k) * pdiv (coeff d (defect p k θ)) else 0 := rfl theorem coeff_corr_of_ne {θ : MvPowerSeries τ (WittVector p k)} {n : ℕ} {d : τ →₀ ℕ} (hd : d.degree ≠ n + 2) : coeff d (corr θ n) = 0 := by rw [coeff_corr, if_neg hd] def approx (c : τ → WittVector p k) : ℕ → MvPowerSeries τ (WittVector p k) | 0 => ∑ s, C (c s) * X s | n + 1 => approx c n + corr (approx c n) n theorem approx_succ (c : τ → WittVector p k) (n : ℕ) : approx c (n + 1) = approx c n + corr (approx c n) n := rfl theorem coeff_approx_zero (c : τ → WittVector p k) (d : τ →₀ ℕ) : coeff d (approx c 0) = ∑ s, if d = Finsupp.single s 1 then c s else 0 := by show coeff d (∑ s, C (c s) * X s) = _ rw [map_sum] refine Finset.sum_congr rfl fun s _ => ?_ rw [coeff_C_mul, coeff_X] split_ifs <;> simp theorem coeff_approx_zero_of_degree_ne_one (c : τ → WittVector p k) {d : τ →₀ ℕ} (hd : d.degree ≠ 1) : coeff d (approx c 0) = 0 := by rw [coeff_approx_zero] refine Finset.sum_eq_zero fun s _ => ?_ rw [if_neg] rintro rfl exact hd (Finsupp.degree_single s 1) theorem coeff_single_approx_zero (c : τ → WittVector p k) (t : τ) : coeff (Finsupp.single t 1) (approx c 0) = c t := by rw [coeff_approx_zero, Finset.sum_eq_single t] · rw [if_pos rfl] · intro s _ hst rw [if_neg] intro h exact hst (Finsupp.single_left_injective one_ne_zero h).symm · intro h exact absurd (Finset.mem_univ t) h theorem coeff_approx_of_le (c : τ → WittVector p k) {n m : ℕ} (hnm : n ≤ m) {d : τ →₀ ℕ} (hd : d.degree ≤ n + 1) : coeff d (approx c m) = coeff d (approx c n) := by induction m with | zero => have hn0 : n = 0 := by omega subst hn0 rfl | succ m IH => rcases Nat.lt_or_ge n (m + 1) with hlt | hge · rw [approx_succ, map_add, coeff_corr_of_ne (by omega), add_zero] exact IH (by omega) · have hn : n = m + 1 := by omega subst hn rfl theorem constantCoeff_approx (c : τ → WittVector p k) (n : ℕ) : constantCoeff (approx c n) = 0 := by have h0 : ((0 : τ →₀ ℕ)).degree = 0 := (Finsupp.degree_eq_zero_iff (0 : τ →₀ ℕ)).mpr rfl rw [← coeff_zero_eq_constantCoeff_apply, coeff_approx_of_le c (Nat.zero_le n) (by omega), coeff_approx_zero_of_degree_ne_one c (by omega)] theorem coeff_single_approx (c : τ → WittVector p k) (n : ℕ) (t : τ) : coeff (Finsupp.single t 1) (approx c n) = c t := by rw [coeff_approx_of_le c (Nat.zero_le n) (by rw [Finsupp.degree_single]), coeff_single_approx_zero] theorem coeff_defect_approx (c : τ → WittVector p k) (n : ℕ) {e : τ →₀ ℕ} (he : e.degree ≤ n + 1) : coeff e (defect p k (approx c n)) = 0 := by have hf : HasSubst (fvec p k τ) := hasSubst_fvec induction n generalizing e with | zero => have hlin0 : ∀ e' : τ →₀ ℕ, e'.degree < 1 → coeff e' (approx c 0) = 0 := fun e' he' => coeff_approx_zero_of_degree_ne_one c (by omega) rw [defect, map_sub, map_add, coeff_C_mul, coeff_subst_fvec hlin0 he, MvFormalGroup.coeff_pow_eq_zero_of_degree_lt (constantCoeff_approx c 0) (by have := two_le_card (k := k); omega), add_zero] rcases eq_zero_or_single_of_degree_le_one he with rfl | ⟨s, rfl⟩ · rw [coeff_zero_eq_constantCoeff_apply, constantCoeff_approx, mul_zero, mul_zero, sub_self] · rw [Finsupp.degree_single, pow_one, sub_self] | succ n IH => set θ := approx c n with hθ have hθ0 : constantCoeff θ = 0 := constantCoeff_approx c n have hκ : ∀ e' : τ →₀ ℕ, e'.degree < n + 2 → coeff e' (corr θ n) = 0 := fun e' he' => coeff_corr_of_ne (by omega) have hκ0 : constantCoeff (corr θ n) = 0 := by rw [← coeff_zero_eq_constantCoeff_apply] exact hκ 0 (by rw [map_zero]; omega) have hθ'0 : constantCoeff (θ + corr θ n) = 0 := by rw [map_add, hθ0, hκ0, add_zero] have hpow : coeff e ((θ + corr θ n) ^ Fintype.card k) = coeff e (θ ^ Fintype.card k) := MvFormalGroup.coeff_pow_sub_congr (N := n + 2) (by omega) hθ'0 hθ0 (fun e' he' => by rw [map_add, hκ e' he', add_zero]) (by have := two_le_card (k := k); omega) have hexp : coeff e (defect p k (θ + corr θ n)) = coeff e (defect p k θ) + ((p : WittVector p k) * coeff e (corr θ n) - coeff e (subst (fvec p k τ) (corr θ n))) := by simp only [defect, map_sub, map_add, coeff_C_mul, mul_add, subst_add hf, hpow] ring rw [approx_succ, hexp] rcases Nat.lt_or_ge e.degree (n + 2) with hlt | hge · rw [IH (by omega), coeff_subst_fvec hκ (le_of_lt hlt), hκ e hlt, mul_zero, mul_zero, sub_self, add_zero] · have hedeg : e.degree = n + 2 := by omega rw [coeff_subst_fvec hκ (le_of_eq hedeg), hedeg, coeff_corr, if_pos hedeg] set u : (WittVector p k)ˣ := (isUnit_one_sub_pow (p := p) (k := k) n).unit with hu have hu' : (u : WittVector p k) = 1 - (p : WittVector p k) ^ (n + 1) := rfl have hdiv := pdiv_spec (exists_coeff_defect_eq_mul θ e) set y := pdiv (coeff e (defect p k θ)) with hy rw [hdiv] have hinv : (u : WittVector p k) * ((u⁻¹ : (WittVector p k)ˣ) : WittVector p k) = 1 := Units.mul_inv u linear_combination (-((p : WittVector p k) * y)) * hinv + ((p : WittVector p k) * y * ((u⁻¹ : (WittVector p k)ˣ) : WittVector p k)) * hu' def ltSeries (c : τ → WittVector p k) : MvPowerSeries τ (WittVector p k) := fun d => coeff d (approx c d.degree) theorem coeff_ltSeries (c : τ → WittVector p k) (d : τ →₀ ℕ) : coeff d (ltSeries c) = coeff d (approx c d.degree) := rfl theorem coeff_ltSeries_of_le (c : τ → WittVector p k) {n : ℕ} {d : τ →₀ ℕ} (hd : d.degree ≤ n + 1) : coeff d (ltSeries c) = coeff d (approx c n) := by rw [coeff_ltSeries] rcases Nat.lt_or_ge d.degree (n + 1) with h | h · rcases Nat.eq_zero_or_pos d.degree with h0 | hpos · rw [h0] exact (coeff_approx_of_le c (Nat.zero_le n) (by omega)).symm · rw [coeff_approx_of_le c (show d.degree - 1 ≤ d.degree by omega) (by omega)] exact (coeff_approx_of_le c (show d.degree - 1 ≤ n by omega) (by omega)).symm · exact coeff_approx_of_le c (by omega) (by omega) theorem constantCoeff_ltSeries (c : τ → WittVector p k) : constantCoeff (ltSeries c) = 0 := by rw [← coeff_zero_eq_constantCoeff_apply, coeff_ltSeries_of_le c (n := 0) (by rw [map_zero]; omega), coeff_zero_eq_constantCoeff_apply, constantCoeff_approx] theorem coeff_single_ltSeries (c : τ → WittVector p k) (t : τ) : coeff (Finsupp.single t 1) (ltSeries c) = c t := by rw [coeff_ltSeries_of_le c (n := 0) (by rw [Finsupp.degree_single]), coeff_single_approx] theorem coeff_defect_congr {θ θ' : MvPowerSeries τ (WittVector p k)} {n : ℕ} (h : ∀ e : τ →₀ ℕ, e.degree ≤ n → coeff e θ = coeff e θ') {d : τ →₀ ℕ} (hd : d.degree ≤ n) : coeff d (defect p k θ) = coeff d (defect p k θ') := by have hf : HasSubst (fvec p k τ) := hasSubst_fvec have hpow : coeff d (θ ^ Fintype.card k) = coeff d (θ' ^ Fintype.card k) := MvFormalGroup.coeff_pow_congr h hd have hsub : coeff d (subst (fvec p k τ) θ) = coeff d (subst (fvec p k τ) θ') := by rw [← sub_eq_zero, ← map_sub, ← subst_sub hf, coeff_subst hf, finsum_eq_zero_of_forall_eq_zero] intro m rcases Nat.lt_or_ge d.degree m.degree with hlt | hge · rw [MvFormalGroup.coeff_finsuppProd_pow_eq_zero_of_degree_lt constantCoeff_fvec hlt, smul_zero] · rw [map_sub, h m (by omega), sub_self, zero_smul] rw [defect, defect, map_sub, map_sub, map_add, map_add, coeff_C_mul, coeff_C_mul, h d hd, hpow, hsub] theorem comm_ltSeries (c : τ → WittVector p k) : Comm p k (ltSeries c) := by unfold Comm rw [← sub_eq_zero] change defect p k (ltSeries c) = 0 refine MvPowerSeries.ext fun d => ?_ rw [map_zero, coeff_defect_congr (θ' := approx c d.degree) (n := d.degree) (fun e he => coeff_ltSeries_of_le c (by omega)) le_rfl] exact coeff_defect_approx c d.degree (Nat.le_succ _) end Exists end CerednikDrinfeld.LubinTateLemma end universe u v in open CerednikDrinfeld.LubinTateLemma in theorem CerednikDrinfeld.LubinTateLemma.existsUnique_series (p : ℕ) [Fact p.Prime] (k : Type u) [Field k] [Fintype k] [CharP k p] (τ : Type v) [Finite τ] (c : τ → WittVector p k) : ∃! φ : MvPowerSeries τ (WittVector p k), MvPowerSeries.constantCoeff φ = 0 ∧ (∀ s, MvPowerSeries.coeff (Finsupp.single s 1) φ = c s) ∧ MvPowerSeries.C (p : WittVector p k) * φ + φ ^ Fintype.card k = MvPowerSeries.subst (fun s => MvPowerSeries.C (p : WittVector p k) * MvPowerSeries.X s + MvPowerSeries.X s ^ Fintype.card k) φ := by classical haveI : Fintype τ := Fintype.ofFinite τ refine ⟨ltSeries c, ⟨constantCoeff_ltSeries c, coeff_single_ltSeries c, comm_ltSeries c⟩, ?_⟩ rintro ψ ⟨hψ0, hψ1, hψ⟩ exact eq_of_comm hψ0 (constantCoeff_ltSeries c) (fun s => by rw [hψ1, coeff_single_ltSeries]) hψ (comm_ltSeries c) set_option autoImplicit false set_option linter.unusedSectionVars false noncomputable section open MvPowerSeries CerednikDrinfeld CerednikDrinfeld.SpecialFormal namespace CerednikDrinfeld.LubinTate universe u v variable {p : ℕ} [Fact p.Prime] instance instFintypeGaloisFieldTwo : Fintype (GaloisField p 2) := Fintype.ofFinite _ theorem card_GF : Fintype.card (GaloisField p 2) = p ^ 2 := by rw [← Nat.card_eq_fintype_card, GaloisField.card p 2 two_ne_zero] theorem two_le_card : 2 ≤ Fintype.card (GaloisField p 2) := Fintype.one_lt_card local notation "𝕆" => Zp2 p local notation "𝔮" => Fintype.card (GaloisField p 2) theorem frobenius_frobenius (a : 𝕆) : WittVector.frobenius (WittVector.frobenius a) = a := by ext n rw [WittVector.coeff_frobenius_charP, WittVector.coeff_frobenius_charP, ← pow_mul, ← sq, ← card_GF, FiniteField.pow_card] theorem exists_pow_ne : ∃ ω : GaloisField p 2, ω ^ p ≠ ω := by classical by_contra h push Not at h have hp1 : 1 < p := (Fact.out : p.Prime).one_lt set P : Polynomial (GaloisField p 2) := Polynomial.X ^ p - Polynomial.X with hP have hP0 : P ≠ 0 := FiniteField.X_pow_card_sub_X_ne_zero _ hp1 have hdeg : P.natDegree = p := FiniteField.X_pow_card_sub_X_natDegree_eq _ hp1 have hroots : ∀ ω : GaloisField p 2, ω ∈ P.roots := by intro ω rw [Polynomial.mem_roots hP0, Polynomial.IsRoot, Polynomial.eval_sub, Polynomial.eval_pow, Polynomial.eval_X, h ω, sub_self] have hcard : Fintype.card (GaloisField p 2) ≤ p := by calc Fintype.card (GaloisField p 2) = (Finset.univ : Finset (GaloisField p 2)).card := Finset.card_univ.symm _ ≤ P.roots.toFinset.card := Finset.card_le_card fun ω _ => Multiset.mem_toFinset.mpr (hroots ω) _ ≤ Multiset.card P.roots := Multiset.toFinset_card_le _ _ ≤ P.natDegree := Polynomial.card_roots' P _ = p := hdeg rw [card_GF, sq] at hcard have : p * p ≤ p * 1 := by simpa using hcard have := Nat.le_of_mul_le_mul_left this (by omega) omega theorem exists_isUnit_frobenius_sub : ∃ a : 𝕆, IsUnit (WittVector.frobenius a - a) := by obtain ⟨ω, hω⟩ := exists_pow_ne (p := p) refine ⟨WittVector.teichmuller p ω, WittVector.isUnit_of_coeff_zero_ne_zero _ ?_⟩ rw [← WittVector.constantCoeff_apply, map_sub, WittVector.constantCoeff_apply, WittVector.constantCoeff_apply, WittVector.coeff_frobenius_charP, WittVector.teichmuller_coeff_zero] exact sub_ne_zero.mpr hω variable (p) def fvec (τ : Type*) : τ → MvPowerSeries τ 𝕆 := fun s => C (p : 𝕆) * X s + X s ^ 𝔮 def Comm {τ : Type*} (φ : MvPowerSeries τ 𝕆) : Prop := C (p : 𝕆) * φ + φ ^ 𝔮 = subst (fvec p τ) φ theorem lt_existsUnique (τ : Type*) [Finite τ] (c : τ → 𝕆) : ∃! φ : MvPowerSeries τ 𝕆, constantCoeff φ = 0 ∧ (∀ s, coeff (Finsupp.single s 1) φ = c s) ∧ Comm p φ := CerednikDrinfeld.LubinTateLemma.existsUnique_series p (GaloisField p 2) τ c def lt (τ : Type*) [Finite τ] (c : τ → 𝕆) : MvPowerSeries τ 𝕆 := (lt_existsUnique p τ c).exists.choose variable {p} section LT variable {τ : Type*} theorem lt_spec [Finite τ] (c : τ → 𝕆) : constantCoeff (lt p τ c) = 0 ∧ (∀ s, coeff (Finsupp.single s 1) (lt p τ c) = c s) ∧ Comm p (lt p τ c) := (lt_existsUnique p τ c).exists.choose_spec theorem constantCoeff_lt [Finite τ] (c : τ → 𝕆) : constantCoeff (lt p τ c) = 0 := (lt_spec c).1 theorem coeff_single_lt [Finite τ] (c : τ → 𝕆) (s : τ) : coeff (Finsupp.single s 1) (lt p τ c) = c s := (lt_spec c).2.1 s theorem comm_lt [Finite τ] (c : τ → 𝕆) : Comm p (lt p τ c) := (lt_spec c).2.2 theorem eq_of_comm [Finite τ] {φ ψ : MvPowerSeries τ 𝕆} (hφ0 : constantCoeff φ = 0) (hψ0 : constantCoeff ψ = 0) (hφ : Comm p φ) (hψ : Comm p ψ) (h1 : ∀ s, coeff (Finsupp.single s 1) φ = coeff (Finsupp.single s 1) ψ) : φ = ψ := (lt_existsUnique p τ fun s => coeff (Finsupp.single s 1) ψ).unique ⟨hφ0, h1, hφ⟩ ⟨hψ0, fun _ => rfl, hψ⟩ theorem constantCoeff_fvec (s : τ) : constantCoeff (fvec p τ s) = 0 := by have h0 : 𝔮 ≠ 0 := by have := two_le_card (p := p); omega simp only [fvec, map_add, map_mul, constantCoeff_C, constantCoeff_X, mul_zero, map_pow, zero_pow h0, add_zero] theorem hasSubst_fvec [Finite τ] : HasSubst (fvec p τ) := hasSubst_of_constantCoeff_zero constantCoeff_fvec theorem coeff_single_X_pow_card [DecidableEq τ] (s t : τ) : coeff (Finsupp.single t 1) ((X s : MvPowerSeries τ 𝕆) ^ 𝔮) = 0 := by rw [coeff_X_pow, if_neg] intro h have := congrArg (fun d => d t) h simp only [Finsupp.single_eq_same] at this by_cases hts : t = s · subst hts rw [Finsupp.single_eq_same] at this have := two_le_card (p := p) omega · rw [Finsupp.single_eq_of_ne hts] at this exact one_ne_zero this theorem coeff_single_fvec [DecidableEq τ] (s t : τ) : coeff (Finsupp.single t 1) (fvec p τ s) = if t = s then (p : 𝕆) else 0 := by rw [fvec, map_add, coeff_C_mul, coeff_index_single_X, coeff_single_X_pow_card, add_zero] split_ifs <;> simp theorem comm_X [Finite τ] (s : τ) : Comm p (X s : MvPowerSeries τ 𝕆) := by unfold Comm rw [subst_X hasSubst_fvec] rfl theorem comm_fvec [Finite τ] (s : τ) : Comm p (fvec p τ s) := by have hf : HasSubst (fvec p τ) := hasSubst_fvec unfold Comm conv_rhs => rw [fvec] rw [subst_add hf, subst_mul hf, subst_C, subst_pow hf, subst_X hf] theorem comm_subst {σ : Type*} [Finite σ] [Finite τ] {φ : MvPowerSeries σ 𝕆} (hφ : Comm p φ) {a : σ → MvPowerSeries τ 𝕆} (ha0 : ∀ s, constantCoeff (a s) = 0) (ha : ∀ s, Comm p (a s)) : Comm p (subst a φ) := by have hsa : HasSubst a := hasSubst_of_constantCoeff_zero ha0 unfold Comm at * calc C (p : 𝕆) * subst a φ + subst a φ ^ 𝔮 = subst a (C (p : 𝕆) * φ + φ ^ 𝔮) := by rw [subst_add hsa, subst_mul hsa, subst_pow hsa, subst_C] _ = subst a (subst (fvec p σ) φ) := by rw [hφ] _ = subst (fun s => subst a (fvec p σ s)) φ := subst_comp_subst_apply hasSubst_fvec hsa φ _ = subst (fun s => subst (fvec p τ) (a s)) φ := by congr 1 funext s show subst a (C (p : 𝕆) * X s + X s ^ 𝔮) = _ rw [subst_add hsa, subst_mul hsa, subst_C, subst_pow hsa, subst_X hsa] exact ha s _ = subst (fvec p τ) (subst a φ) := (subst_comp_subst_apply hsa hasSubst_fvec φ).symm theorem comm_subst_X {σ : Type*} [Finite σ] [Finite τ] {φ : MvPowerSeries σ 𝕆} (hφ : Comm p φ) (e : σ → τ) : Comm p (subst (fun s => (X (e s) : MvPowerSeries τ 𝕆)) φ) := comm_subst hφ (fun _ => constantCoeff_X _) fun _ => comm_X _ theorem constantCoeff_subst_of {σ : Type*} [Finite σ] {φ : MvPowerSeries σ 𝕆} (hφ : constantCoeff φ = 0) {a : σ → MvPowerSeries τ 𝕆} (ha0 : ∀ s, constantCoeff (a s) = 0) : constantCoeff (subst a φ) = 0 := constantCoeff_subst_eq_zero (hasSubst_of_constantCoeff_zero ha0) ha0 hφ theorem coeff_single_subst_lt {σ : Type*} [Fintype σ] [Fintype τ] (c : σ → 𝕆) {a : σ → MvPowerSeries τ 𝕆} (ha0 : ∀ s, constantCoeff (a s) = 0) (t : τ) : coeff (Finsupp.single t 1) (subst a (lt p σ c)) = ∑ s, c s * coeff (Finsupp.single t 1) (a s) := by rw [MvFormalGroup.coeff_single_subst ha0] simp only [coeff_single_lt] end LT section FrobeniusInvariance variable {τ : Type*} local notation "σ" => (WittVector.frobenius : Zp2 p →+* Zp2 p) theorem map_frobenius_fvec (s : τ) : MvPowerSeries.map σ (fvec p τ s) = fvec p τ s := by rw [fvec, map_add, map_mul, map_C, map_natCast, map_X, map_pow, map_X] theorem comm_map_frobenius [Finite τ] {φ : MvPowerSeries τ 𝕆} (hφ : Comm p φ) : Comm p (MvPowerSeries.map σ φ) := by unfold Comm at * have h := congrArg (MvPowerSeries.map σ) hφ rw [map_add, map_mul, map_C, map_natCast, map_pow, map_subst hasSubst_fvec] at h rw [h] congr 1 funext s exact map_frobenius_fvec s theorem map_frobenius_lt [Finite τ] (c : τ → 𝕆) : MvPowerSeries.map σ (lt p τ c) = lt p τ fun s => σ (c s) := by classical refine eq_of_comm ?_ (constantCoeff_lt _) (comm_map_frobenius (comm_lt c)) (comm_lt _) fun s => ?_ · rw [constantCoeff_map, constantCoeff_lt, map_zero] · rw [coeff_map, coeff_single_lt, coeff_single_lt] end FrobeniusInvariance section Sigma variable (p) def sigmaSeries : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆 := lt p (Fin 1 ⊕ Fin 1) fun _ => 1 def act₁ (a : 𝕆) : MvPowerSeries (Fin 1) 𝕆 := lt p (Fin 1) fun _ => a variable {p} theorem constantCoeff_sigmaSeries : constantCoeff (sigmaSeries p) = 0 := constantCoeff_lt _ theorem comm_sigmaSeries : Comm p (sigmaSeries p) := comm_lt _ theorem coeff_single_sigmaSeries (v : Fin 1 ⊕ Fin 1) : coeff (Finsupp.single v 1) (sigmaSeries p) = 1 := by rw [sigmaSeries, coeff_single_lt] theorem coeff_single_subst_sigmaSeries {τ : Type*} [Fintype τ] {a : Fin 1 ⊕ Fin 1 → MvPowerSeries τ 𝕆} (ha0 : ∀ v, constantCoeff (a v) = 0) (t : τ) : coeff (Finsupp.single t 1) (subst a (sigmaSeries p)) = coeff (Finsupp.single t 1) (a (Sum.inl 0)) + coeff (Finsupp.single t 1) (a (Sum.inr 0)) := by rw [sigmaSeries, coeff_single_subst_lt _ ha0, Fintype.sum_sum_type] simp only [one_mul, Finset.univ_unique, Fin.default_eq_zero, Fin.isValue, Finset.sum_singleton] theorem constantCoeff_act₁ (a : 𝕆) : constantCoeff (act₁ p a) = 0 := constantCoeff_lt _ theorem comm_act₁ (a : 𝕆) : Comm p (act₁ p a) := comm_lt _ theorem coeff_single_act₁ (a : 𝕆) (s : Fin 1) : coeff (Finsupp.single s 1) (act₁ p a) = a := by rw [act₁, coeff_single_lt] theorem coeff_single_subst_act₁ {τ : Type*} [Fintype τ] (a : 𝕆) {b : Fin 1 → MvPowerSeries τ 𝕆} (hb0 : ∀ s, constantCoeff (b s) = 0) (t : τ) : coeff (Finsupp.single t 1) (subst b (act₁ p a)) = a * coeff (Finsupp.single t 1) (b 0) := by rw [act₁, coeff_single_subst_lt _ hb0] simp only [Finset.univ_unique, Fin.default_eq_zero, Fin.isValue, Finset.sum_singleton] theorem hasSubst_fin1 {τ : Type*} {x : MvPowerSeries τ 𝕆} (hx : constantCoeff x = 0) : HasSubst (fun _ : Fin 1 => x) := hasSubst_of_constantCoeff_zero fun _ => hx variable (p) in def sigma : MvFormalGroup 1 𝕆 where toPowerSeries := fun _ => sigmaSeries p constantCoeff_eq_zero := fun _ => constantCoeff_sigmaSeries coeff_single_inl i j := by rw [coeff_single_sigmaSeries, if_pos (Subsingleton.elim i j)] coeff_single_inr i j := by rw [coeff_single_sigmaSeries, if_pos (Subsingleton.elim i j)] assoc i := by classical have hB : ∀ s : Fin 1 ⊕ Fin 1, constantCoeff ((Sum.elim (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ (Fin 1 ⊕ Fin 1)) 𝕆)) fun l => X (Sum.inr (Sum.inl l))) s) = 0 := by rintro (l | l) <;> exact constantCoeff_X _ have hC : ∀ s : Fin 1 ⊕ Fin 1, constantCoeff ((Sum.elim (fun l => (X (Sum.inr (Sum.inl l)) : MvPowerSeries (Fin 1 ⊕ (Fin 1 ⊕ Fin 1)) 𝕆)) fun l => X (Sum.inr (Sum.inr l))) s) = 0 := by rintro (l | l) <;> exact constantCoeff_X _ have hBv : (Sum.elim (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ (Fin 1 ⊕ Fin 1)) 𝕆)) fun l => X (Sum.inr (Sum.inl l))) = fun s => X (Sum.elim (fun l => Sum.inl l) (fun l => Sum.inr (Sum.inl l)) s) := by funext s; rcases s with l | l <;> rfl have hCv : (Sum.elim (fun l => (X (Sum.inr (Sum.inl l)) : MvPowerSeries (Fin 1 ⊕ (Fin 1 ⊕ Fin 1)) 𝕆)) fun l => X (Sum.inr (Sum.inr l))) = fun s => X (Sum.elim (fun l => Sum.inr (Sum.inl l)) (fun l => Sum.inr (Sum.inr l)) s) := by funext s; rcases s with l | l <;> rfl have hA : ∀ s : Fin 1 ⊕ Fin 1, constantCoeff ((Sum.elim (fun _ : Fin 1 => subst (Sum.elim (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ (Fin 1 ⊕ Fin 1)) 𝕆)) fun l => X (Sum.inr (Sum.inl l))) (sigmaSeries p)) fun j => X (Sum.inr (Sum.inr j))) s) = 0 := by rintro (j | j) · exact constantCoeff_subst_of constantCoeff_sigmaSeries hB · exact constantCoeff_X _ have hA' : ∀ s : Fin 1 ⊕ Fin 1, constantCoeff ((Sum.elim (fun j => (X (Sum.inl j) : MvPowerSeries (Fin 1 ⊕ (Fin 1 ⊕ Fin 1)) 𝕆)) fun _ : Fin 1 => subst (Sum.elim (fun l => (X (Sum.inr (Sum.inl l)) : MvPowerSeries (Fin 1 ⊕ (Fin 1 ⊕ Fin 1)) 𝕆)) fun l => X (Sum.inr (Sum.inr l))) (sigmaSeries p)) s) = 0 := by rintro (j | j) · exact constantCoeff_X _ · exact constantCoeff_subst_of constantCoeff_sigmaSeries hC refine eq_of_comm (constantCoeff_subst_of constantCoeff_sigmaSeries hA) (constantCoeff_subst_of constantCoeff_sigmaSeries hA') ?_ ?_ ?_ · refine comm_subst comm_sigmaSeries hA ?_ rintro (j | j) · show Comm p (subst _ (sigmaSeries p)) rw [hBv] exact comm_subst_X comm_sigmaSeries _ · exact comm_X _ · refine comm_subst comm_sigmaSeries hA' ?_ rintro (j | j) · exact comm_X _ · show Comm p (subst _ (sigmaSeries p)) rw [hCv] exact comm_subst_X comm_sigmaSeries _ · intro t rw [coeff_single_subst_sigmaSeries hA, coeff_single_subst_sigmaSeries hA'] simp only [Sum.elim_inl, Sum.elim_inr] rw [coeff_single_subst_sigmaSeries hB, coeff_single_subst_sigmaSeries hC] simp only [Sum.elim_inl, Sum.elim_inr] exact add_assoc _ _ _ @[simp] theorem sigma_toPowerSeries (i : Fin 1) : (sigma p).toPowerSeries i = sigmaSeries p := rfl instance sigma_isComm : (sigma p).IsComm where comm i := by classical have hS : ∀ s : Fin 1 ⊕ Fin 1, constantCoeff ((Sum.elim (fun j => (X (Sum.inr j) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) fun j => X (Sum.inl j)) s) = 0 := by rintro (j | j) <;> exact constantCoeff_X _ have hSv : (Sum.elim (fun j => (X (Sum.inr j) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) fun j => X (Sum.inl j)) = fun s => X (Sum.swap s) := by funext s; rcases s with l | l <;> rfl show subst _ (sigmaSeries p) = sigmaSeries p refine eq_of_comm (constantCoeff_subst_of constantCoeff_sigmaSeries hS) constantCoeff_sigmaSeries ?_ comm_sigmaSeries ?_ · rw [hSv] exact comm_subst_X comm_sigmaSeries _ · intro t rw [coeff_single_subst_sigmaSeries hS, coeff_single_sigmaSeries] simp only [Sum.elim_inl, Sum.elim_inr, coeff_index_single_X] rcases t with l | l <;> rw [Fin.fin_one_eq_zero l] <;> simp theorem constantCoeff_homFamily₁ {φ : MvPowerSeries (Fin 1) 𝕆} (hφ : constantCoeff φ = 0) : ∀ s : Fin 1 ⊕ Fin 1, constantCoeff ((Sum.elim (fun _ : Fin 1 => subst (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) fun _ : Fin 1 => subst (fun l => (X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) s) = 0 := by rintro (j | j) <;> exact constantCoeff_subst_of hφ (fun l => constantCoeff_X _) theorem subst_sigma_eq_of_comm {φ : MvPowerSeries (Fin 1) 𝕆} (h0 : constantCoeff φ = 0) (hc : Comm p φ) : subst (sigma p).toPowerSeries φ = subst (Sum.elim (fun _ : Fin 1 => subst (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) fun _ : Fin 1 => subst (fun l => (X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) (sigmaSeries p) := by classical have hF : ∀ j : Fin 1, constantCoeff ((sigma p).toPowerSeries j) = 0 := fun _ => constantCoeff_sigmaSeries have hA := constantCoeff_homFamily₁ h0 refine eq_of_comm (constantCoeff_subst_of h0 hF) (constantCoeff_subst_of constantCoeff_sigmaSeries hA) (comm_subst hc hF fun _ => comm_sigmaSeries) (comm_subst comm_sigmaSeries hA ?_) ?_ · rintro (j | j) <;> exact comm_subst_X hc _ · intro t rw [coeff_single_subst_sigmaSeries hA, MvFormalGroup.coeff_single_subst hF] simp only [Sum.elim_inl, Sum.elim_inr, sigma_toPowerSeries, coeff_single_sigmaSeries, Finset.univ_unique, Fin.default_eq_zero, Fin.isValue, Finset.sum_singleton] rw [MvFormalGroup.coeff_single_subst (fun l => constantCoeff_X _), MvFormalGroup.coeff_single_subst (fun l => constantCoeff_X _)] simp only [coeff_index_single_X, Finset.univ_unique, Fin.default_eq_zero, Fin.isValue, Finset.sum_singleton, mul_ite, mul_one, mul_zero] rcases t with l | l <;> rw [Fin.fin_one_eq_zero l] <;> simp theorem subst_sigma_act₁ (a : 𝕆) : subst (sigma p).toPowerSeries (act₁ p a) = subst (Sum.elim (fun _ : Fin 1 => subst (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) (act₁ p a)) fun _ : Fin 1 => subst (fun l => (X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) (act₁ p a)) (sigmaSeries p) := subst_sigma_eq_of_comm (constantCoeff_act₁ a) (comm_act₁ a) theorem act₁_one : act₁ p 1 = X 0 := by classical refine eq_of_comm (constantCoeff_act₁ 1) (constantCoeff_X 0) (comm_act₁ 1) (comm_X 0) fun s => ?_ rw [coeff_single_act₁, coeff_index_single_X, if_pos (Subsingleton.elim s 0)] theorem act₁_zero : act₁ p 0 = 0 := by classical have h0 : Comm p (0 : MvPowerSeries (Fin 1) 𝕆) := by unfold Comm have hq : Fintype.card (GaloisField p 2) ≠ 0 := by have := two_le_card (p := p); omega rw [mul_zero, zero_pow hq, add_zero, ← coe_substAlgHom hasSubst_fvec, map_zero] refine eq_of_comm (constantCoeff_act₁ 0) (map_zero _) (comm_act₁ 0) h0 fun s => ?_ rw [coeff_single_act₁, map_zero] theorem act₁_mul (a b : 𝕆) : act₁ p (a * b) = subst (fun _ : Fin 1 => act₁ p b) (act₁ p a) := by classical refine eq_of_comm (constantCoeff_act₁ _) (constantCoeff_subst_of (constantCoeff_act₁ a) (fun _ => constantCoeff_act₁ b)) (comm_act₁ _) (comm_subst (comm_act₁ a) (fun _ => constantCoeff_act₁ b) fun _ => comm_act₁ b) fun s => ?_ rw [coeff_single_act₁, coeff_single_subst_act₁ a (fun _ => constantCoeff_act₁ b), coeff_single_act₁] theorem act₁_add (a b : 𝕆) : act₁ p (a + b) = subst (Sum.elim (fun _ : Fin 1 => act₁ p a) fun _ : Fin 1 => act₁ p b) (sigmaSeries p) := by classical have hab : ∀ s : Fin 1 ⊕ Fin 1, constantCoeff ((Sum.elim (fun _ : Fin 1 => act₁ p a) fun _ : Fin 1 => act₁ p b) s) = 0 := by rintro (j | j) <;> exact constantCoeff_act₁ _ refine eq_of_comm (constantCoeff_act₁ _) (constantCoeff_subst_of constantCoeff_sigmaSeries hab) (comm_act₁ _) (comm_subst comm_sigmaSeries hab ?_) fun s => ?_ · rintro (j | j) <;> exact comm_act₁ _ · rw [coeff_single_act₁, coeff_single_subst_sigmaSeries hab] simp only [Sum.elim_inl, Sum.elim_inr, coeff_single_act₁] theorem act₁_natCast_p : act₁ p (p : 𝕆) = C (p : 𝕆) * X 0 + X 0 ^ Fintype.card (GaloisField p 2) := by classical refine eq_of_comm (constantCoeff_act₁ _) (constantCoeff_fvec 0) (comm_act₁ _) (comm_fvec 0) fun s => ?_ show _ = coeff _ (fvec p (Fin 1) 0) rw [coeff_single_act₁, coeff_single_fvec, if_pos (Subsingleton.elim s 0)] theorem map_frobenius_sigmaSeries : MvPowerSeries.map WittVector.frobenius (sigmaSeries p) = sigmaSeries p := by rw [sigmaSeries, map_frobenius_lt] simp only [map_one] theorem map_frobenius_act₁ (a : 𝕆) : MvPowerSeries.map WittVector.frobenius (act₁ p a) = act₁ p (WittVector.frobenius a) := by rw [act₁, map_frobenius_lt] rfl end Sigma section Reduction instance instIsCommMap {g : ℕ} {R S : Type*} [CommRing R] [CommRing S] (F : MvFormalGroup g R) [F.IsComm] (f : R →+* S) : (F.map f).IsComm := by constructor intro i have key := congrArg (MvPowerSeries.map f) (MvFormalGroup.IsComm.comm (F := F) i) have hS : HasSubst (Sum.elim (fun j => (X (Sum.inr j) : MvPowerSeries (Fin g ⊕ Fin g) R)) fun j => X (Sum.inl j)) := by apply hasSubst_of_constantCoeff_zero rintro (j | j) <;> exact constantCoeff_X _ rw [map_subst hS] at key have hfam : (fun s => MvPowerSeries.map f (Sum.elim (fun j => (X (Sum.inr j) : MvPowerSeries (Fin g ⊕ Fin g) R)) (fun j => X (Sum.inl j)) s)) = Sum.elim (fun j => (X (Sum.inr j) : MvPowerSeries (Fin g ⊕ Fin g) S)) fun j => X (Sum.inl j) := by funext s rcases s with j | j <;> simp only [Sum.elim_inl, Sum.elim_inr, MvPowerSeries.map_X] rw [hfam] at key exact key variable {B : Type u} [CommRing B] theorem map_homIdentity₁ (f : 𝕆 →+* B) {F : Fin 1 → MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆} (hF : ∀ i, constantCoeff (F i) = 0) {G : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆} {φ : MvPowerSeries (Fin 1) 𝕆} (hφ : constantCoeff φ = 0) (h : subst F φ = subst (Sum.elim (fun _ : Fin 1 => subst (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) fun _ : Fin 1 => subst (fun l => (X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) G) : subst (fun i => MvPowerSeries.map f (F i)) (MvPowerSeries.map f φ) = subst (Sum.elim (fun _ : Fin 1 => subst (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) B)) (MvPowerSeries.map f φ)) fun _ : Fin 1 => subst (fun l => (X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) B)) (MvPowerSeries.map f φ)) (MvPowerSeries.map f G) := by have hXl : ∀ l : Fin 1, constantCoeff ((X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) = 0 := fun l => constantCoeff_X _ have hXr : ∀ l : Fin 1, constantCoeff ((X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) = 0 := fun l => constantCoeff_X _ have hA : HasSubst (Sum.elim (fun _ : Fin 1 => subst (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) fun _ : Fin 1 => subst (fun l => (X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) := by apply hasSubst_of_constantCoeff_zero rintro (j | j) · exact constantCoeff_subst_eq_zero (hasSubst_of_constantCoeff_zero hXl) hXl hφ · exact constantCoeff_subst_eq_zero (hasSubst_of_constantCoeff_zero hXr) hXr hφ have key := congrArg (MvPowerSeries.map f) h rw [map_subst (hasSubst_of_constantCoeff_zero hF), map_subst hA] at key have hAmap : (fun s => MvPowerSeries.map f (Sum.elim (fun _ : Fin 1 => subst (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) (fun _ : Fin 1 => subst (fun l => (X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) 𝕆)) φ) s)) = Sum.elim (fun _ : Fin 1 => subst (fun l => (X (Sum.inl l) : MvPowerSeries (Fin 1 ⊕ Fin 1) B)) (MvPowerSeries.map f φ)) fun _ : Fin 1 => subst (fun l => (X (Sum.inr l) : MvPowerSeries (Fin 1 ⊕ Fin 1) B)) (MvPowerSeries.map f φ) := by funext s rcases s with j | j · show MvPowerSeries.map f (subst _ φ) = _ rw [map_subst (hasSubst_of_constantCoeff_zero hXl)] simp only [MvPowerSeries.map_X, Sum.elim_inl] · show MvPowerSeries.map f (subst _ φ) = _ rw [map_subst (hasSubst_of_constantCoeff_zero hXr)] simp only [MvPowerSeries.map_X, Sum.elim_inr] rw [hAmap] at key exact key variable (j : Zp2 p →+* B) def sigmaBar : MvFormalGroup 1 B := (sigma p).map j @[simp] theorem sigmaBar_toPowerSeries (i : Fin 1) : (sigmaBar j).toPowerSeries i = MvPowerSeries.map j (sigmaSeries p) := rfl instance sigmaBar_isComm : (sigmaBar j).IsComm := instIsCommMap _ _ def rhoEnd (a : 𝕆) : MvFormalGroup.End (sigmaBar j) where toPowerSeries := fun _ => MvPowerSeries.map j (act₁ p a) constantCoeff_eq_zero := fun _ => by rw [constantCoeff_map, constantCoeff_act₁, map_zero] subst_eq i := by rw [Fin.fin_one_eq_zero i] exact map_homIdentity₁ j (fun _ => constantCoeff_sigmaSeries) (constantCoeff_act₁ a) (subst_sigma_act₁ a) @[simp] theorem rhoEnd_toPowerSeries (a : 𝕆) (i : Fin 1) : MvFormalGroup.Hom.toPowerSeries (rhoEnd j a) i = MvPowerSeries.map j (act₁ p a) := rfl theorem toPowerSeries_fin1 {F : MvFormalGroup 1 B} (e : MvFormalGroup.End F) : MvFormalGroup.Hom.toPowerSeries e = fun _ => MvFormalGroup.Hom.toPowerSeries e 0 := by funext i; rw [Fin.fin_one_eq_zero i] def rho : 𝕆 →+* MvFormalGroup.End (sigmaBar j) where toFun := rhoEnd j map_one' := by apply MvFormalGroup.Hom.ext funext i rw [rhoEnd_toPowerSeries, act₁_one, MvPowerSeries.map_X, MvFormalGroup.End.toPowerSeries_one, Fin.fin_one_eq_zero i] map_mul' a b := by apply MvFormalGroup.Hom.ext funext i rw [rhoEnd_toPowerSeries, MvFormalGroup.End.toPowerSeries_mul, act₁_mul, map_subst (hasSubst_fin1 (constantCoeff_act₁ b))] rfl map_zero' := by apply MvFormalGroup.Hom.ext funext i rw [rhoEnd_toPowerSeries, act₁_zero, map_zero, MvFormalGroup.End.toPowerSeries_zero] map_add' a b := by apply MvFormalGroup.Hom.ext funext i have hab : HasSubst (Sum.elim (fun _ : Fin 1 => act₁ p a) fun _ : Fin 1 => act₁ p b) := by apply hasSubst_of_constantCoeff_zero rintro (l | l) <;> exact constantCoeff_act₁ _ rw [rhoEnd_toPowerSeries, MvFormalGroup.End.toPowerSeries_add, act₁_add, map_subst hab] dsimp only rw [sigmaBar_toPowerSeries] congr 1 funext s rcases s with l | l <;> rfl theorem rho_toPowerSeries (a : 𝕆) (i : Fin 1) : MvFormalGroup.Hom.toPowerSeries (rho j a) i = MvPowerSeries.map j (act₁ p a) := rfl theorem coeff_single_rho (a : 𝕆) : coeff (Finsupp.single 0 1) (MvFormalGroup.Hom.toPowerSeries (rho j a) 0) = j a := by rw [rho_toPowerSeries, coeff_map, coeff_single_act₁] variable [CharP B p] theorem rho_p_toPowerSeries : MvFormalGroup.Hom.toPowerSeries (rho j (p : 𝕆)) 0 = (X 0 : MvPowerSeries (Fin 1) B) ^ p ^ 2 := by rw [rho_toPowerSeries, act₁_natCast_p, map_add, map_mul, map_C, map_natCast, CharP.cast_eq_zero, map_zero, zero_mul, zero_add, map_pow, MvPowerSeries.map_X, card_GF] theorem j_eq_teichmuller (x : 𝕆) : j x = j (WittVector.teichmuller p (x.coeff 0)) := by have hmem : x - WittVector.teichmuller p (x.coeff 0) ∈ Ideal.span {(p : 𝕆)} := by rw [WittVector.mem_span_p_iff_coeff_zero_eq_zero, ← WittVector.constantCoeff_apply, map_sub, WittVector.constantCoeff_apply, WittVector.constantCoeff_apply, WittVector.teichmuller_coeff_zero, sub_self] obtain ⟨d, hd⟩ := Ideal.mem_span_singleton'.mp hmem have : j (x - WittVector.teichmuller p (x.coeff 0)) = 0 := by rw [← hd, map_mul, map_natCast, CharP.cast_eq_zero, mul_zero] rwa [map_sub, sub_eq_zero] at this theorem j_frobenius (x : 𝕆) : j (WittVector.frobenius x) = j x ^ p := by rw [j_eq_teichmuller j (WittVector.frobenius x), j_eq_teichmuller j x, WittVector.coeff_frobenius_charP, map_pow, map_pow] theorem map_frobenius_map_j {τ : Type*} (y : MvPowerSeries τ 𝕆) : MvPowerSeries.map (frobenius B p) (MvPowerSeries.map j y) = MvPowerSeries.map j (MvPowerSeries.map WittVector.frobenius y) := by ext m simp only [coeff_map, frobenius_def, j_frobenius] theorem hp0 : (p : ℕ) ≠ 0 := (Fact.out : p.Prime).ne_zero theorem pow_p_eq_expand_map {τ : Type*} (y : MvPowerSeries τ B) : y ^ p = expand p hp0 (MvPowerSeries.map (frobenius B p) y) := by rw [← map_frobenius_expand p hp0, map_expand] theorem sigmaBar_pow_p : (MvPowerSeries.map j (sigmaSeries p)) ^ p = subst (fun s : Fin 1 ⊕ Fin 1 => (X s : MvPowerSeries (Fin 1 ⊕ Fin 1) B) ^ p) (MvPowerSeries.map j (sigmaSeries p)) := by rw [pow_p_eq_expand_map, map_frobenius_map_j, map_frobenius_sigmaSeries, expand, coe_substAlgHom] def phi : MvFormalGroup.End (sigmaBar j) where toPowerSeries := fun _ => (X 0 : MvPowerSeries (Fin 1) B) ^ p constantCoeff_eq_zero := fun _ => by rw [map_pow, constantCoeff_X, zero_pow hp0] subst_eq i := by rw [Fin.fin_one_eq_zero i, sigmaBar_toPowerSeries, subst_pow (sigmaBar j).hasSubst_toPowerSeries, subst_X (sigmaBar j).hasSubst_toPowerSeries, sigmaBar_toPowerSeries, sigmaBar_pow_p] congr 1 funext s rcases s with l | l · rw [Fin.fin_one_eq_zero l, Sum.elim_inl, subst_pow (hasSubst_of_constantCoeff_zero fun _ => constantCoeff_X _), subst_X (hasSubst_of_constantCoeff_zero fun _ => constantCoeff_X _)] · rw [Fin.fin_one_eq_zero l, Sum.elim_inr, subst_pow (hasSubst_of_constantCoeff_zero fun _ => constantCoeff_X _), subst_X (hasSubst_of_constantCoeff_zero fun _ => constantCoeff_X _)] @[simp] theorem phi_toPowerSeries (i : Fin 1) : MvFormalGroup.Hom.toPowerSeries (phi j) i = (X 0 : MvPowerSeries (Fin 1) B) ^ p := rfl theorem phi_mul_rho (a : 𝕆) : phi j * rho j a = rho j (WittVector.frobenius a) * phi j := by apply MvFormalGroup.Hom.ext funext i rw [MvFormalGroup.End.toPowerSeries_mul, MvFormalGroup.End.toPowerSeries_mul] dsimp only rw [phi_toPowerSeries, subst_pow (rho j a).hasSubst_toPowerSeries, subst_X (rho j a).hasSubst_toPowerSeries, rho_toPowerSeries, rho_toPowerSeries, pow_p_eq_expand_map, map_frobenius_map_j, map_frobenius_act₁, expand, coe_substAlgHom] congr 1 funext s rw [phi_toPowerSeries, Fin.fin_one_eq_zero s] theorem phi_mul_phi : phi j * phi j = rho j (p : 𝕆) := by apply MvFormalGroup.Hom.ext funext i rw [MvFormalGroup.End.toPowerSeries_mul] dsimp only rw [phi_toPowerSeries, subst_pow (phi j).hasSubst_toPowerSeries, subst_X (phi j).hasSubst_toPowerSeries, phi_toPowerSeries, ← pow_mul, ← sq, Fin.fin_one_eq_zero i, rho_p_toPowerSeries] theorem rho_mul_comm (a b : 𝕆) : rho j a * rho j b = rho j b * rho j a := by rw [← map_mul, ← map_mul, mul_comm] end Reduction end CerednikDrinfeld.LubinTate end