Fermat's Last Theorem in Lean 4

← all definition modules

Definitions/Def_MvFormalGroup_CartierModuleBaseChange.lean

definition module

Base change of Cartier modules along ring homomorphisms

Throughout, p is a prime, R, S, T are commutative rings, and \Phi, \Phi' (over R), \Psi, \Psi' (over S) are multivariate formal group laws of dimensions d, d'. The module first records that coefficientwise application of a ring homomorphism respects the symmetry condition IsComm (whose content is that each component of the law is invariant under interchanging the two blocks of variables): isComm_map and the corresponding instance give (F.map f).IsComm from F.IsComm, and map_map_ringHom, map_ringHom_id' give (\Phi.\mathrm{map}\,f).\mathrm{map}\,g=\Phi.\mathrm{map}(g\circ f) and \Phi.\mathrm{map}\,\mathrm{id}=\Phi.

A group of lemmas in the WittLaw namespace states that the standard substitution families have integral coefficients, so that MvPowerSeries.map f carries addFam, verFam, frobFam, curveFam to themselves, teichFam p a to teichFam p (f a) and the Witt-multiplication family mulFam p w to mulFam p (WittVector.map f w) (with the corresponding statement map_mulPoly for the polynomials).

The central definition is base change of Cartier modules. An element of CartierModule p Φ is a family of d power series in countably many variables with vanishing constant coefficients satisfying the substitution identity with respect to addFam. Given f\colon R\to S and an identification h\colon \Phi.\mathrm{map}\,f=\Psi, baseChangeEqFun f h m is the element of CartierModule p Ψ whose components are the images of those of m under MvPowerSeries.map f; for commutative laws, baseChangeEq f h packages this as an additive map CartierModule p Φ →+ CartierModule p Ψ, and baseChange f is the case \Psi=\Phi.\mathrm{map}\,f with the identification given by reflexivity.

The remaining results describe this map: the components are literally the mapped series; two identifications yield the same components; it is the identity along RingHom.id, composes along g\circ f, and is injective when f is; it commutes with precomposition by families corresponding under f, hence with frobenius, with verschiebung when both R and S have characteristic p, with their iterates, with homothety a (becoming homothety (f a)), with the Witt-vector action (w\bullet m becoming WittVector.map f w acting) and with nsmul; it commutes with post-composition by homomorphisms or endomorphisms of laws whose coefficients correspond under f; and \mathrm{tangent}(m_S)=f\circ\mathrm{tangent}(m), \mathrm{curve}(m_S)_j=\mathrm{PowerSeries.map}\,f(\mathrm{curve}(m)_j). A final example computes base change on the linear curves addLinear p v of the additive law, giving addLinear p (f ∘ v).

Relation to Mathlib

Mathlib supplies the ambient machinery used here (multivariate power series with substitution, WittVector and WittVector.map, the Witt multiplication polynomials), but multivariate formal group laws, their homomorphisms and the Cartier modules CartierModule p Φ with their Frobenius, Verschiebung, homothety and Witt-vector operators are the project's own notions; base change of these is defined here.

Where it is used

These definitions make the Cartier module of a commutative formal group law functorial in the base ring, so that the same presentation \mathrm{Hom}(\widehat W,\Phi) can be used simultaneously over a ring and over its quotients, subrings and extensions, as required when formal groups are compared over varying bases.

References

  1. P. Cartier, Modules associés à un groupe formel commutatif. Courbes typiques, C. R. Acad. Sci. Paris 265 (1967), 129–132
  2. M. Lazard, Commutative Formal Groups, Lecture Notes in Mathematics 443, Springer, 1975
  3. M. Hazewinkel, Formal Groups and Applications, Academic Press, 1978

References are suggested automatically and have not been individually verified.

English text generated automatically from the Lean source; the Lean statement is authoritative.

Source file: Definitions/Def_MvFormalGroup_CartierModuleBaseChange.lean

Imports

Imported by

Declarations

Source

import Mathlib
import Definitions.Def_MvFormalGroup_NegV2
import Definitions.Def_MvFormalGroup_CartierModule
import Definitions.Def_MvFormalGroup_CartierModuleHomothety
import Definitions.Def_MvFormalGroup_CartierModuleWittAction

set_option autoImplicit false

noncomputable section

universe u v w

open MvPowerSeries

namespace MvFormalGroup

variable {p : ℕ} [hp : Fact p.Prime] {d d' : ℕ}
variable {R : Type u} [CommRing R] {S : Type v} [CommRing S] {T : Type w} [CommRing T]

omit hp in

theorem isComm_map (F : MvFormalGroup d 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 d ⊕ Fin d) 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 d ⊕ Fin d) R))
      (fun j => X (Sum.inl j)) s))
      = Sum.elim
        (fun j => (X (Sum.inr j) : MvPowerSeries (Fin d ⊕ Fin d) S))
        fun j => X (Sum.inl j) := by
    funext s
    rcases s with j | j <;> simp [map_X]
  rw [hfam] at key
  exact key

instance instIsCommMapRingHom (F : MvFormalGroup d R) [F.IsComm] (f : R →+* S) :
    (F.map f).IsComm :=
  isComm_map F f

omit hp in
@[simp] theorem toPowerSeries_map_ringHom (F : MvFormalGroup d R) (f : R →+* S) (i : Fin d) :
    (F.map f).toPowerSeries i = MvPowerSeries.map f (F.toPowerSeries i) := rfl

omit hp in

theorem map_map_ringHom (F : MvFormalGroup d R) (f : R →+* S) (g : S →+* T) :
    (F.map f).map g = F.map (g.comp f) := by
  refine MvFormalGroup.ext (funext fun i => ?_)
  show MvPowerSeries.map g (MvPowerSeries.map f (F.toPowerSeries i)) = MvPowerSeries.map (g.comp f) _
  rw [MvPowerSeries.map_comp]
  rfl

omit hp in
theorem map_ringHom_id' (F : MvFormalGroup d R) : F.map (RingHom.id R) = F := by
  refine MvFormalGroup.ext (funext fun i => ?_)
  show MvPowerSeries.map (RingHom.id R) (F.toPowerSeries i) = _
  rw [MvPowerSeries.map_id]
  rfl

namespace WittLaw

omit hp in

theorem constantCoeff_map_family {σ τ : Type*} {a : σ → MvPowerSeries τ R}
    (ha : ∀ s, (a s).constantCoeff = 0) (f : R →+* S) (s : σ) :
    (MvPowerSeries.map f (a s)).constantCoeff = 0 := by
  rw [constantCoeff_map, ha s, map_zero]

omit hp in

theorem coe_mvPolynomial_map {σ : Type*} (f : R →+* S) (P : MvPolynomial σ R) :
    ((MvPolynomial.map f P : MvPolynomial σ S) : MvPowerSeries σ S) =
      MvPowerSeries.map f (P : MvPowerSeries σ R) := by
  ext n
  rw [MvPolynomial.coeff_coe, MvPolynomial.coeff_map, coeff_map, MvPolynomial.coeff_coe]

theorem map_addFam (f : R →+* S) (n : ℕ) :
    MvPowerSeries.map f (addFam p R n) = addFam p S n := by
  rw [addFam, addFam, ← coe_mvPolynomial_map, MvPolynomial.map_map]
  congr 2
  ext x <;> simp

omit hp in

theorem map_verFam (f : R →+* S) (n : ℕ) :
    MvPowerSeries.map f (verFam R n) = verFam S n := by
  cases n with
  | zero => exact map_zero _
  | succ n => exact map_X f n

omit hp in

theorem map_frobFam (f : R →+* S) (n : ℕ) :
    MvPowerSeries.map f (frobFam p R n) = frobFam p S n := by
  show MvPowerSeries.map f (X n ^ p) = X n ^ p
  rw [map_pow, map_X]

omit hp in

theorem map_teichFam (f : R →+* S) (a : R) (n : ℕ) :
    MvPowerSeries.map f (teichFam p a n) = teichFam p (f a) n := by
  rw [teichFam_apply, teichFam_apply, smul_eq_C_mul, smul_eq_C_mul, map_mul, map_C, map_X, map_pow]

theorem map_mulPoly (f : R →+* S) (w : WittVector p R) (n : ℕ) :
    MvPolynomial.map f (mulPoly p w n) = mulPoly p (WittVector.map f w) n := by
  rw [mulPoly_eq_peval, mulPoly_eq_peval,
    WittVector.map_peval (MvPolynomial.map f) (WittVector.wittMul p n)]
  congr 1
  funext i m
  fin_cases i
  · show MvPolynomial.map f (MvPolynomial.C (w.coeff m)) = MvPolynomial.C ((WittVector.map f w).coeff m)
    rw [MvPolynomial.map_C, WittVector.map_coeff]
  · show MvPolynomial.map f (MvPolynomial.X m) = MvPolynomial.X m
    rw [MvPolynomial.map_X]

theorem map_mulFam (f : R →+* S) (w : WittVector p R) (n : ℕ) :
    MvPowerSeries.map f (mulFam p w n) = mulFam p (WittVector.map f w) n := by
  rw [mulFam_apply, mulFam_apply, ← coe_mvPolynomial_map, map_mulPoly]

end WittLaw

namespace CartierModule

open WittLaw

variable {Φ : MvFormalGroup d R} {Φ' : MvFormalGroup d' R}
variable {Ψ : MvFormalGroup d S} {Ψ' : MvFormalGroup d' S}

omit hp in

theorem map_curveFam (f : R →+* S) (n : ℕ) :
    MvPowerSeries.map f (curveFam R n) = curveFam S n := by
  cases n with
  | zero => exact map_X f ()
  | succ n => exact map_zero _

omit hp in

theorem map_blkX (f : R →+* S) (i : Fin 2) :
    (fun m => MvPowerSeries.map f ((fun m => (X (i, m) : MvPowerSeries (Fin 2 × ℕ) R)) m)) =
      fun m => (X (i, m) : MvPowerSeries (Fin 2 × ℕ) S) := by
  funext m
  exact map_X f (i, m)

def baseChangeEqFun (f : R →+* S) (h : Φ.map f = Ψ) (m : CartierModule p Φ) : CartierModule p Ψ where
  toPowerSeries := fun j => MvPowerSeries.map f (m.toPowerSeries j)
  constantCoeff_eq_zero := fun j => constantCoeff_map_family m.constantCoeff_eq_zero f j
  subst_eq := by
    intro j
    subst h
    have hm := m.constantCoeff_eq_zero
    have hm' : ∀ l, (MvPowerSeries.map f (m.toPowerSeries l)).constantCoeff = 0 :=
      constantCoeff_map_family hm f
    have key := congrArg (MvPowerSeries.map f) (m.subst_addFam j)
    have hE : HasSubst (Sum.elim (inBlk 0 m.toPowerSeries) (inBlk 1 m.toPowerSeries)) := by
      apply hasSubst_of_constantCoeff_zero
      rintro (l | l)
      · exact constantCoeff_inBlk 0 hm l
      · exact constantCoeff_inBlk 1 hm l
    rw [map_subst (hasSubst_addFam p R), map_subst hE] at key
    have hA : (fun n => MvPowerSeries.map f (addFam p R n)) = addFam p S := funext (map_addFam f)
    rw [hA] at key
    have hblk : ∀ (i : Fin 2) (l : Fin d), MvPowerSeries.map f (inBlk i m.toPowerSeries l) =
        inBlk i (fun l => MvPowerSeries.map f (m.toPowerSeries l)) l := by
      intro i l
      rw [inBlk_apply, inBlk_apply, map_subst (hasSubst_blk i)]
      congr 1
      funext n
      exact map_X f (i, n)
    have hfam : (fun s => MvPowerSeries.map f
        (Sum.elim (inBlk 0 m.toPowerSeries) (inBlk 1 m.toPowerSeries) s)) =
        Sum.elim (inBlk 0 fun l => MvPowerSeries.map f (m.toPowerSeries l))
          (inBlk 1 fun l => MvPowerSeries.map f (m.toPowerSeries l)) := by
      funext s
      rcases s with l | l
      · exact hblk 0 l
      · exact hblk 1 l
    rw [hfam] at key
    exact key

@[simp] theorem toPowerSeries_baseChangeEqFun (f : R →+* S) (h : Φ.map f = Ψ) (m : CartierModule p Φ)
    (j : Fin d) : (baseChangeEqFun f h m).toPowerSeries j = MvPowerSeries.map f (m.toPowerSeries j) :=
  rfl

theorem map_sumElim (f : R →+* S) {σ : Type*} (a b : Fin d → MvPowerSeries σ R) :
    (fun s => MvPowerSeries.map f (Sum.elim a b s)) =
      Sum.elim (fun l => MvPowerSeries.map f (a l)) fun l => MvPowerSeries.map f (b l) := by
  funext s
  rcases s with l | l <;> rfl

def baseChangeEq [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ) :
    CartierModule p Φ →+ CartierModule p Ψ where
  toFun := baseChangeEqFun f h
  map_zero' := CartierModule.ext (funext fun j => by
    show MvPowerSeries.map f 0 = 0
    exact map_zero _)
  map_add' m m' := CartierModule.ext (funext fun j => by
    show MvPowerSeries.map f (subst (Sum.elim m.toPowerSeries m'.toPowerSeries) (Φ.toPowerSeries j)) =
      subst (Sum.elim (fun l => MvPowerSeries.map f (m.toPowerSeries l))
        fun l => MvPowerSeries.map f (m'.toPowerSeries l)) (Ψ.toPowerSeries j)
    have hS : HasSubst (Sum.elim m.toPowerSeries m'.toPowerSeries) := by
      apply hasSubst_of_constantCoeff_zero
      rintro (l | l)
      · exact m.constantCoeff_eq_zero l
      · exact m'.constantCoeff_eq_zero l
    rw [map_subst hS, map_sumElim, ← h]
    rfl)

@[simp] theorem toPowerSeries_baseChangeEq [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    (m : CartierModule p Φ) (j : Fin d) :
    (baseChangeEq f h m).toPowerSeries j = MvPowerSeries.map f (m.toPowerSeries j) :=
  rfl

theorem baseChangeEq_apply [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    (m : CartierModule p Φ) : baseChangeEq f h m = baseChangeEqFun f h m := rfl

abbrev baseChange [Φ.IsComm] (f : R →+* S) : CartierModule p Φ →+ CartierModule p (Φ.map f) :=
  baseChangeEq f rfl

theorem baseChangeEq_id [Φ.IsComm] (h : Φ.map (RingHom.id R) = Φ) (m : CartierModule p Φ) :
    baseChangeEq (RingHom.id R) h m = m :=
  CartierModule.ext (funext fun j => by
    show MvPowerSeries.map (RingHom.id R) (m.toPowerSeries j) = _
    rw [MvPowerSeries.map_id]
    rfl)

theorem baseChangeEq_baseChangeEq [Φ.IsComm] [Ψ.IsComm] {Χ : MvFormalGroup d T} [Χ.IsComm]
    (f : R →+* S) (g : S →+* T) (h : Φ.map f = Ψ) (h' : Ψ.map g = Χ) (h'' : Φ.map (g.comp f) = Χ)
    (m : CartierModule p Φ) :
    baseChangeEq g h' (baseChangeEq f h m) = baseChangeEq (g.comp f) h'' m :=
  CartierModule.ext (funext fun j => by
    show MvPowerSeries.map g (MvPowerSeries.map f (m.toPowerSeries j)) =
      MvPowerSeries.map (g.comp f) (m.toPowerSeries j)
    rw [MvPowerSeries.map_comp]
    rfl)

theorem toPowerSeries_baseChangeEq_eq [Φ.IsComm] [Ψ.IsComm] {Ψ₁ : MvFormalGroup d S} [Ψ₁.IsComm]
    (f : R →+* S) (h : Φ.map f = Ψ) (h₁ : Φ.map f = Ψ₁) (m : CartierModule p Φ) :
    (baseChangeEq f h m).toPowerSeries = (baseChangeEq f h₁ m).toPowerSeries := rfl

theorem baseChangeEq_injective [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    (hf : Function.Injective f) : Function.Injective (baseChangeEq (p := p) f h) := by
  intro m m' hmm
  refine CartierModule.ext (funext fun j => ?_)
  have hj := congrArg (fun x : CartierModule p Ψ => x.toPowerSeries j) hmm
  simp only [toPowerSeries_baseChangeEq] at hj
  ext e
  apply hf
  rw [← coeff_map, ← coeff_map, hj]

theorem baseChangeEq_precomp [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    {u : ℕ → MvPowerSeries ℕ R} {u' : ℕ → MvPowerSeries ℕ S} (hu : IsEndo p u) (hu' : IsEndo p u')
    (huu' : ∀ n, MvPowerSeries.map f (u n) = u' n) (m : CartierModule p Φ) :
    baseChangeEq f h (precomp hu m) = precomp hu' (baseChangeEq f h m) :=
  CartierModule.ext (funext fun j => by
    show MvPowerSeries.map f (subst u (m.toPowerSeries j)) =
      subst u' (MvPowerSeries.map f (m.toPowerSeries j))
    rw [map_subst hu.hasSubst]
    congr 1
    exact funext huu')

theorem baseChangeEq_frobenius [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    (m : CartierModule p Φ) :
    baseChangeEq f h (frobenius m) = frobenius (baseChangeEq f h m) :=
  baseChangeEq_precomp f h isEndo_verFam isEndo_verFam (map_verFam f) m

theorem baseChangeEq_verschiebung [Φ.IsComm] [Ψ.IsComm] [CharP R p] [CharP S p] (f : R →+* S)
    (h : Φ.map f = Ψ) (m : CartierModule p Φ) :
    baseChangeEq f h (verschiebung m) = verschiebung (baseChangeEq f h m) :=
  baseChangeEq_precomp f h isEndo_frobFam isEndo_frobFam (map_frobFam f) m

theorem baseChangeEq_verschiebung_iterate [Φ.IsComm] [Ψ.IsComm] [CharP R p] [CharP S p]
    (f : R →+* S) (h : Φ.map f = Ψ) (n : ℕ) (m : CartierModule p Φ) :
    baseChangeEq f h ((⇑(verschiebung (p := p) (Φ := Φ)))^[n] m) =
      (⇑(verschiebung (p := p) (Φ := Ψ)))^[n] (baseChangeEq f h m) := by
  induction n generalizing m with
  | zero => rfl
  | succ n ih =>
    rw [Function.iterate_succ_apply, Function.iterate_succ_apply, ← baseChangeEq_verschiebung, ih]

theorem baseChangeEq_frobenius_iterate [Φ.IsComm] [Ψ.IsComm]
    (f : R →+* S) (h : Φ.map f = Ψ) (n : ℕ) (m : CartierModule p Φ) :
    baseChangeEq f h ((⇑(frobenius (p := p) (Φ := Φ)))^[n] m) =
      (⇑(frobenius (p := p) (Φ := Ψ)))^[n] (baseChangeEq f h m) := by
  induction n generalizing m with
  | zero => rfl
  | succ n ih =>
    rw [Function.iterate_succ_apply, Function.iterate_succ_apply, ← baseChangeEq_frobenius, ih]

theorem baseChangeEq_homothety [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ) (a : R)
    (m : CartierModule p Φ) :
    baseChangeEq f h (homothety a m) = homothety (f a) (baseChangeEq f h m) :=
  baseChangeEq_precomp f h (isEndo_teichFam a) (isEndo_teichFam (f a)) (map_teichFam f a) m

theorem baseChangeEq_smul_witt [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    (w : WittVector p R) (m : CartierModule p Φ) :
    baseChangeEq f h (w • m) = (WittVector.map f w) • (baseChangeEq f h m) := by
  rw [smul_eq_precomp, smul_eq_precomp]
  exact baseChangeEq_precomp f h (isEndo_mulFam w) (isEndo_mulFam _) (map_mulFam f w) m

theorem baseChangeEq_nsmul [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ) (n : ℕ)
    (m : CartierModule p Φ) : baseChangeEq f h (n • m) = n • baseChangeEq f h m :=
  map_nsmul _ _ _

theorem baseChangeEq_map [Φ.IsComm] [Ψ.IsComm] [Φ'.IsComm] [Ψ'.IsComm] (f : R →+* S)
    (h : Φ.map f = Ψ) (h' : Φ'.map f = Ψ') {φ : Φ.Hom Φ'} {ψ : Ψ.Hom Ψ'}
    (hφψ : ∀ i, ψ.toPowerSeries i = MvPowerSeries.map f (φ.toPowerSeries i)) (m : CartierModule p Φ) :
    baseChangeEq f h' (map φ m) = map ψ (baseChangeEq f h m) :=
  CartierModule.ext (funext fun i => by
    show MvPowerSeries.map f (subst m.toPowerSeries (φ.toPowerSeries i)) =
      subst (fun l => MvPowerSeries.map f (m.toPowerSeries l)) (ψ.toPowerSeries i)
    rw [map_subst m.hasSubst_toPowerSeries, hφψ i])

theorem baseChangeEq_endAct [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    {φ : MvFormalGroup.End Φ} {ψ : MvFormalGroup.End Ψ}
    (hφψ : ∀ i, ψ.toPowerSeries i = MvPowerSeries.map f (φ.toPowerSeries i)) (m : CartierModule p Φ) :
    baseChangeEq f h (endAct φ m) = endAct ψ (baseChangeEq f h m) :=
  baseChangeEq_map f h h hφψ m

theorem tangent_baseChangeEq [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    (m : CartierModule p Φ) : tangent (baseChangeEq f h m) = fun j => f (tangent m j) := by
  funext j
  show coeff (Finsupp.single 0 1) (MvPowerSeries.map f (m.toPowerSeries j)) =
    f (coeff (Finsupp.single 0 1) (m.toPowerSeries j))
  rw [coeff_map]

theorem curve_baseChangeEq [Φ.IsComm] [Ψ.IsComm] (f : R →+* S) (h : Φ.map f = Ψ)
    (m : CartierModule p Φ) (j : Fin d) :
    curve (baseChangeEq f h m) j = PowerSeries.map f (curve m j) := by
  rw [curve_apply, curve_apply]
  show subst (curveFam S) (MvPowerSeries.map f (m.toPowerSeries j)) =
    MvPowerSeries.map f (subst (curveFam R) (m.toPowerSeries j))
  rw [map_subst hasSubst_curveFam]
  congr 1
  funext n
  exact (map_curveFam f n).symm

namespace Examples

theorem baseChange_addLinear (f : R →+* S) (v : Fin d → R)
    (h : (addMv d R).map f = addMv d S) :
    baseChangeEq f h (addLinear p v) = addLinear p (fun j => f (v j)) := by
  refine CartierModule.ext (funext fun j => ?_)
  show MvPowerSeries.map f (v j • (X 0 : MvPowerSeries ℕ R)) = f (v j) • (X 0 : MvPowerSeries ℕ S)
  rw [smul_eq_C_mul, smul_eq_C_mul, map_mul, map_C, map_X]

end Examples

end CartierModule

end MvFormalGroup

end

Statements phrased using this module (93)