import Definitions.Def_MvFormalGroup_NegV2 import Mathlib.RingTheory.AdicCompletion.Topology import Mathlib.RingTheory.Finiteness.Ideal set_option autoImplicit false noncomputable section open MvPowerSeries namespace MvFormalGroup variable {g h k : ℕ} {R : Type*} [CommRing R] section AdicEval variable {S : Type*} [CommRing S] [Algebra R S] {S' : Type*} [CommRing S'] [Algebra R S'] {σ : Type*} def adicEval (J : Ideal S) (x : σ → S) (f : MvPowerSeries σ R) : S := letI : UniformSpace R := ⊥ letI : WithIdeal S := ⟨J⟩ MvPowerSeries.eval₂ (algebraMap R S) x f private theorem isTopologicallyNilpotent_of_mem_radical (J : Ideal S) {a : S} (ha : a ∈ J.radical) : letI : TopologicalSpace S := J.adicTopology IsTopologicallyNilpotent a := by letI : TopologicalSpace S := J.adicTopology obtain ⟨k, hk⟩ := ha show Filter.Tendsto (a ^ ·) Filter.atTop (nhds 0) rw [(J.hasBasis_nhds_zero_adic).tendsto_right_iff] intro n _ filter_upwards [Filter.eventually_ge_atTop (k * n)] with m hm obtain ⟨r, rfl⟩ : ∃ r, m = k * n + r := ⟨m - k * n, by omega⟩ rw [pow_add, pow_mul] exact SetLike.mem_coe.mpr (Ideal.mul_mem_right _ _ (Ideal.pow_mem_pow hk n)) private theorem hasEval_of_mem_radical [Finite σ] (J : Ideal S) {x : σ → S} (hx : ∀ s, x s ∈ J.radical) : letI : TopologicalSpace S := J.adicTopology MvPowerSeries.HasEval x := by letI : TopologicalSpace S := J.adicTopology refine ⟨fun s => isTopologicallyNilpotent_of_mem_radical J (hx s), ?_⟩ rw [Filter.cofinite_eq_bot] exact Filter.tendsto_bot theorem adicEval_coe (J : Ideal S) (x : σ → S) (p : MvPolynomial σ R) : adicEval J x (p : MvPowerSeries σ R) = MvPolynomial.aeval x p := by letI : UniformSpace R := ⊥ letI : WithIdeal S := ⟨J⟩ rw [MvPolynomial.aeval_def] exact MvPowerSeries.eval₂_coe (algebraMap R S) x p theorem adicEval_X (J : Ideal S) (x : σ → S) (s : σ) : adicEval J x (X s : MvPowerSeries σ R) = x s := by letI : UniformSpace R := ⊥ letI : WithIdeal S := ⟨J⟩ exact MvPowerSeries.eval₂_X (algebraMap R S) x s def adicEvalAlgHom [Finite σ] (J : Ideal S) [IsAdicComplete J S] {x : σ → S} (hx : ∀ s, x s ∈ J.radical) : MvPowerSeries σ R →ₐ[R] S := letI : UniformSpace R := ⊥ letI : WithIdeal S := ⟨J⟩ haveI : CompleteSpace S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).1 haveI : T2Space S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).2 haveI : ContinuousSMul R S := DiscreteTopology.instContinuousSMul R S MvPowerSeries.aeval (hasEval_of_mem_radical J hx) theorem coe_adicEvalAlgHom [Finite σ] (J : Ideal S) [IsAdicComplete J S] {x : σ → S} (hx : ∀ s, x s ∈ J.radical) : ⇑(adicEvalAlgHom (R := R) J hx) = adicEval J x := by letI : UniformSpace R := ⊥ letI : WithIdeal S := ⟨J⟩ haveI : CompleteSpace S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).1 haveI : T2Space S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).2 haveI : ContinuousSMul R S := DiscreteTopology.instContinuousSMul R S funext f exact congrFun (MvPowerSeries.coe_aeval (hasEval_of_mem_radical J hx)) f open MvPowerSeries.WithPiTopology in theorem adicEval_mem_radical [Finite σ] (J : Ideal S) [IsAdicComplete J S] {x : σ → S} (hx : ∀ s, x s ∈ J.radical) {f : MvPowerSeries σ R} (hf : f.constantCoeff = 0) : adicEval J x f ∈ J.radical := by letI : UniformSpace R := ⊥ letI : WithIdeal S := ⟨J⟩ haveI : CompleteSpace S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).1 haveI : T2Space S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).2 show MvPowerSeries.eval₂ (algebraMap R S) x f ∈ J.radical have hφ : Continuous (algebraMap R S) := continuous_of_discreteTopology have ha := hasEval_of_mem_radical J hx have hf' : IsTopologicallyNilpotent f := MvPowerSeries.WithPiTopology.isTopologicallyNilpotent_of_constantCoeff_zero hf have hc : Continuous (MvPowerSeries.eval₂Hom hφ ha) := by rw [MvPowerSeries.coe_eval₂Hom] exact MvPowerSeries.continuous_eval₂ hφ ha obtain ⟨n, hn⟩ := (hf'.map hc).exists_pow_mem_of_mem_nhds ((J.hasBasis_nhds_zero_adic).mem_of_mem (i := 1) trivial) rw [MvPowerSeries.coe_eval₂Hom, pow_one] at hn exact ⟨n, hn⟩ theorem adicEval_subst [Finite σ] {τ : Type*} (J : Ideal S) [IsAdicComplete J S] {x : σ → S} (hx : ∀ s, x s ∈ J.radical) {a : τ → MvPowerSeries σ R} (ha : HasSubst a) (f : MvPowerSeries τ R) : adicEval J x (subst a f) = adicEval J (fun t => adicEval J x (a t)) f := by letI : UniformSpace R := ⊥ letI : WithIdeal S := ⟨J⟩ haveI : CompleteSpace S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).1 haveI : T2Space S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).2 exact MvPowerSeries.eval₂_subst ha (hasEval_of_mem_radical J hx) f theorem map_adicEval [Finite σ] (J : Ideal S) [IsAdicComplete J S] (J' : Ideal S') [IsAdicComplete J' S'] (φ : S →ₐ[R] S') (hJ : J.FG) (hφ : ∀ s ∈ J, φ s ∈ J'.radical) {x : σ → S} (hx : ∀ s, x s ∈ J.radical) (f : MvPowerSeries σ R) : φ (adicEval J x f) = adicEval J' (fun s => φ (x s)) f := by letI : UniformSpace R := ⊥ letI : WithIdeal S := ⟨J⟩ letI : WithIdeal S' := ⟨J'⟩ haveI : CompleteSpace S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).1 haveI : T2Space S := ((IsAdic.isAdicComplete_iff (show IsAdic J from rfl)).mp ‹IsAdicComplete J S›).2 haveI : CompleteSpace S' := ((IsAdic.isAdicComplete_iff (show IsAdic J' from rfl)).mp ‹IsAdicComplete J' S'›).1 haveI : T2Space S' := ((IsAdic.isAdicComplete_iff (show IsAdic J' from rfl)).mp ‹IsAdicComplete J' S'›).2 have hle : J.map (φ : S →+* S') ≤ J'.radical := by rw [Ideal.map_le_iff_le_comap] intro s hs exact hφ s hs obtain ⟨m, hm⟩ := Ideal.exists_pow_le_of_le_radical_of_fg hle (hJ.map _) have hcont : Continuous (φ : S →+* S') := by apply continuous_of_continuousAt_zero (φ : S →+* S') rw [ContinuousAt, map_zero, (J.hasBasis_nhds_zero_adic).tendsto_iff (J'.hasBasis_nhds_zero_adic)] intro n _ refine ⟨m * n, trivial, fun s hs => ?_⟩ have hpow : (J ^ (m * n)).map (φ : S →+* S') ≤ J' ^ n := by rw [Ideal.map_pow, pow_mul] exact Ideal.pow_right_mono hm n exact SetLike.mem_coe.mpr (hpow (Ideal.mem_map_of_mem _ (SetLike.mem_coe.mp hs))) have key := congrFun (MvPowerSeries.comp_eval₂ (φ := algebraMap R S) (a := x) continuous_of_discreteTopology (hasEval_of_mem_radical J hx) hcont) f rw [AlgHom.comp_algebraMap] at key exact key theorem adicEval_subst_elim (F : MvFormalGroup g R) {τ : Type*} [Finite τ] (J : Ideal S) [IsAdicComplete J S] {w : τ → S} (hw : ∀ t, w t ∈ J.radical) {u v : Fin g → MvPowerSeries τ R} (hu : ∀ j, (u j).constantCoeff = 0) (hv : ∀ j, (v j).constantCoeff = 0) (i : Fin g) : adicEval J w (subst (Sum.elim u v) (F.toPowerSeries i)) = adicEval J (Sum.elim (fun j => adicEval J w (u j)) fun j => adicEval J w (v j)) (F.toPowerSeries i) := by have hfam : (fun s => adicEval J w (Sum.elim u v s)) = Sum.elim (fun j => adicEval J w (u j)) fun j => adicEval J w (v j) := by funext s rcases s with j | j <;> rfl rw [adicEval_subst J hw (hasSubst_elim hu hv), hfam] private theorem map_mem_radical {J : Ideal S} {J' : Ideal S'} (φ : S →ₐ[R] S') (hφ : ∀ s ∈ J, φ s ∈ J'.radical) {s : S} (hs : s ∈ J.radical) : φ s ∈ J'.radical := by obtain ⟨a, ha⟩ := hs obtain ⟨b, hb⟩ := hφ _ ha refine ⟨a * b, ?_⟩ rw [pow_mul, ← map_pow φ s a] exact hb end AdicEval private theorem forall_sumElim {α β M : Type*} {p : M → Prop} {x : α → M} {y : β → M} (hx : ∀ a, p (x a)) (hy : ∀ b, p (y b)) : ∀ c, p (Sum.elim x y c) := by rintro (a | b) exacts [hx a, hy b] @[ext] structure Points (F : MvFormalGroup g R) (S : Type*) [CommRing S] (J : Ideal S) : Type _ where val : Fin g → S mem_radical : ∀ i, val i ∈ J.radical namespace Points variable {F : MvFormalGroup g R} {S : Type*} [CommRing S] {J : Ideal S} instance instZero : Zero (Points F S J) := ⟨⟨fun _ => 0, fun _ => Submodule.zero_mem _⟩⟩ theorem val_zero : (0 : Points F S J).val = fun _ => 0 := rfl variable [Algebra R S] private theorem adicEval_X_eq (x : Points F S J) : (fun j => adicEval J x.val (X j : MvPowerSeries (Fin g) R)) = x.val := funext fun j => adicEval_X J x.val j variable [IsAdicComplete J S] protected def add (x y : Points F S J) : Points F S J where val i := adicEval J (Sum.elim x.val y.val) (F.toPowerSeries i) mem_radical i := adicEval_mem_radical J (forall_sumElim x.mem_radical y.mem_radical) (F.constantCoeff_eq_zero i) instance instAdd : Add (Points F S J) := ⟨Points.add⟩ theorem val_add (x y : Points F S J) (i : Fin g) : (x + y).val i = adicEval J (Sum.elim x.val y.val) (F.toPowerSeries i) := rfl protected def neg (x : Points F S J) : Points F S J where val i := adicEval J x.val (invSeries F i) mem_radical i := adicEval_mem_radical J x.mem_radical (constantCoeff_invSeries F i) instance instNeg : Neg (Points F S J) := ⟨Points.neg⟩ theorem val_neg (x : Points F S J) (i : Fin g) : (-x).val i = adicEval J x.val (invSeries F i) := rfl protected theorem add_assoc (x y z : Points F S J) : x + y + z = x + (y + z) := by ext i show adicEval J (Sum.elim (fun j => adicEval J (Sum.elim x.val y.val) (F.toPowerSeries j)) z.val) (F.toPowerSeries i) = adicEval J (Sum.elim x.val fun j => adicEval J (Sum.elim y.val z.val) (F.toPowerSeries j)) (F.toPowerSeries i) have hw : ∀ t, Sum.elim x.val (Sum.elim y.val z.val) t ∈ J.radical := forall_sumElim x.mem_radical (forall_sumElim y.mem_radical z.mem_radical) have ha : ∀ j, (X (Sum.inl j) : MvPowerSeries (Fin g ⊕ (Fin g ⊕ Fin g)) R).constantCoeff = 0 := fun j => constantCoeff_X _ have hb : ∀ j, (X (Sum.inr (Sum.inl j)) : MvPowerSeries (Fin g ⊕ (Fin g ⊕ Fin g)) R).constantCoeff = 0 := fun j => constantCoeff_X _ have hc : ∀ j, (X (Sum.inr (Sum.inr j)) : MvPowerSeries (Fin g ⊕ (Fin g ⊕ Fin g)) R).constantCoeff = 0 := fun j => constantCoeff_X _ have hxa : (fun j => adicEval J (Sum.elim x.val (Sum.elim y.val z.val)) (X (Sum.inl j) : MvPowerSeries (Fin g ⊕ (Fin g ⊕ Fin g)) R)) = x.val := funext fun j => adicEval_X _ _ _ have hyb : (fun j => adicEval J (Sum.elim x.val (Sum.elim y.val z.val)) (X (Sum.inr (Sum.inl j)) : MvPowerSeries (Fin g ⊕ (Fin g ⊕ Fin g)) R)) = y.val := funext fun j => adicEval_X _ _ _ have hzc : (fun j => adicEval J (Sum.elim x.val (Sum.elim y.val z.val)) (X (Sum.inr (Sum.inr j)) : MvPowerSeries (Fin g ⊕ (Fin g ⊕ Fin g)) R)) = z.val := funext fun j => adicEval_X _ _ _ have hin1 : (fun j => adicEval J (Sum.elim x.val (Sum.elim y.val z.val)) (subst (Sum.elim (fun l => (X (Sum.inl l) : MvPowerSeries (Fin g ⊕ (Fin g ⊕ Fin g)) R)) fun l => X (Sum.inr (Sum.inl l))) (F.toPowerSeries j))) = fun j => adicEval J (Sum.elim x.val y.val) (F.toPowerSeries j) := by funext j rw [adicEval_subst_elim F J hw ha hb, hxa, hyb] have hin2 : (fun j => adicEval J (Sum.elim x.val (Sum.elim y.val z.val)) (subst (Sum.elim (fun l => (X (Sum.inr (Sum.inl l)) : MvPowerSeries (Fin g ⊕ (Fin g ⊕ Fin g)) R)) fun l => X (Sum.inr (Sum.inr l))) (F.toPowerSeries j))) = fun j => adicEval J (Sum.elim y.val z.val) (F.toPowerSeries j) := by funext j rw [adicEval_subst_elim F J hw hb hc, hyb, hzc] have key := congrArg (adicEval J (Sum.elim x.val (Sum.elim y.val z.val))) (subst_elim_assoc F ha hb hc i) rw [adicEval_subst_elim F J hw (constantCoeff_subst_elim F ha hb) hc, adicEval_subst_elim F J hw ha (constantCoeff_subst_elim F hb hc), hin1, hzc, hxa, hin2] at key exact key protected theorem zero_add (x : Points F S J) : 0 + x = x := by ext i show adicEval J (Sum.elim (fun _ => 0) x.val) (F.toPowerSeries i) = x.val i have h0 : ∀ j : Fin g, (0 : MvPowerSeries (Fin g) R).constantCoeff = 0 := fun _ => map_zero _ have hX : ∀ j : Fin g, (X j : MvPowerSeries (Fin g) R).constantCoeff = 0 := fun j => constantCoeff_X _ have hz : (fun _ : Fin g => adicEval J x.val (0 : MvPowerSeries (Fin g) R)) = fun _ => 0 := by funext j rw [← coe_adicEvalAlgHom J x.mem_radical, map_zero] have key := congrArg (adicEval J x.val) (subst_elim_zero_left F hX i) rw [adicEval_subst_elim F J x.mem_radical h0 hX, hz, adicEval_X_eq, adicEval_X] at key exact key protected theorem add_zero (x : Points F S J) : x + 0 = x := by ext i show adicEval J (Sum.elim x.val fun _ => 0) (F.toPowerSeries i) = x.val i have h0 : ∀ j : Fin g, (0 : MvPowerSeries (Fin g) R).constantCoeff = 0 := fun _ => map_zero _ have hX : ∀ j : Fin g, (X j : MvPowerSeries (Fin g) R).constantCoeff = 0 := fun j => constantCoeff_X _ have hz : (fun _ : Fin g => adicEval J x.val (0 : MvPowerSeries (Fin g) R)) = fun _ => 0 := by funext j rw [← coe_adicEvalAlgHom J x.mem_radical, map_zero] have key := congrArg (adicEval J x.val) (subst_elim_zero_right F hX i) rw [adicEval_subst_elim F J x.mem_radical hX h0, hz, adicEval_X_eq, adicEval_X] at key exact key protected theorem neg_add_cancel (x : Points F S J) : -x + x = 0 := by ext i show adicEval J (Sum.elim (fun j => adicEval J x.val (invSeries F j)) x.val) (F.toPowerSeries i) = 0 have hX : ∀ j : Fin g, (X j : MvPowerSeries (Fin g) R).constantCoeff = 0 := fun j => constantCoeff_X _ have hz : adicEval J x.val (0 : MvPowerSeries (Fin g) R) = 0 := by rw [← coe_adicEvalAlgHom J x.mem_radical, map_zero] have key := congrArg (adicEval J x.val) (subst_elim_invSeries_X F i) rw [adicEval_subst_elim F J x.mem_radical (constantCoeff_invSeries F) hX, adicEval_X_eq, hz] at key exact key instance instAddGroup : AddGroup (Points F S J) where add := (· + ·) zero := 0 neg := fun x => -x add_assoc := Points.add_assoc zero_add := Points.zero_add add_zero := Points.add_zero neg_add_cancel := Points.neg_add_cancel nsmul := nsmulRec zsmul := zsmulRec protected theorem add_comm [IsComm F] (x y : Points F S J) : x + y = y + x := by ext i show adicEval J (Sum.elim x.val y.val) (F.toPowerSeries i) = adicEval J (Sum.elim y.val x.val) (F.toPowerSeries i) have hw : ∀ t, Sum.elim x.val y.val t ∈ J.radical := forall_sumElim x.mem_radical y.mem_radical have ha : ∀ j, (X (Sum.inl j) : MvPowerSeries (Fin g ⊕ Fin g) R).constantCoeff = 0 := fun j => constantCoeff_X _ have hb : ∀ j, (X (Sum.inr j) : MvPowerSeries (Fin g ⊕ Fin g) R).constantCoeff = 0 := fun j => constantCoeff_X _ have hxa : (fun j => adicEval J (Sum.elim x.val y.val) (X (Sum.inl j) : MvPowerSeries (Fin g ⊕ Fin g) R)) = x.val := funext fun j => adicEval_X _ _ _ have hyb : (fun j => adicEval J (Sum.elim x.val y.val) (X (Sum.inr j) : MvPowerSeries (Fin g ⊕ Fin g) R)) = y.val := funext fun j => adicEval_X _ _ _ have key := congrArg (adicEval J (Sum.elim x.val y.val)) (subst_elim_comm F ha hb i) rw [adicEval_subst_elim F J hw ha hb, adicEval_subst_elim F J hw hb ha, hxa, hyb] at key exact key instance instAddCommGroup [IsComm F] : AddCommGroup (Points F S J) := { Points.instAddGroup with add_comm := Points.add_comm } theorem val_nsmul (n : ℕ) (x : Points F S J) : (n • x).val = fun i => adicEval J x.val (F.nthSeries n i) := by induction n with | zero => funext i rw [zero_nsmul] show (0 : S) = adicEval J x.val (0 : MvPowerSeries (Fin g) R) rw [← coe_adicEvalAlgHom J x.mem_radical, map_zero] | succ n ih => funext i rw [succ_nsmul] show adicEval J (Sum.elim (n • x).val x.val) (F.toPowerSeries i) = adicEval J x.val (subst (Sum.elim (F.nthSeries n) fun j => X j) (F.toPowerSeries i)) rw [adicEval_subst_elim F J x.mem_radical (constantCoeff_nthSeries F n) (fun j => constantCoeff_X j), ih, adicEval_X_eq] end Points namespace Hom variable {F : MvFormalGroup g R} {G : MvFormalGroup h R} {H : MvFormalGroup k R} {S : Type*} [CommRing S] [Algebra R S] {J : Ideal S} [IsAdicComplete J S] def evalPoints (φ : Hom F G) : Points F S J →+ Points G S J := AddMonoidHom.mk' (fun x => ⟨fun i => adicEval J x.val (φ.toPowerSeries i), fun i => adicEval_mem_radical J x.mem_radical (φ.constantCoeff_eq_zero i)⟩) (fun x y => by ext i show adicEval J (fun j => adicEval J (Sum.elim x.val y.val) (F.toPowerSeries j)) (φ.toPowerSeries i) = adicEval J (Sum.elim (fun j => adicEval J x.val (φ.toPowerSeries j)) fun j => adicEval J y.val (φ.toPowerSeries j)) (G.toPowerSeries i) have hw : ∀ t, Sum.elim x.val y.val t ∈ J.radical := forall_sumElim x.mem_radical y.mem_radical have hl : HasSubst (fun l : Fin g => (X (Sum.inl l) : MvPowerSeries (Fin g ⊕ Fin g) R)) := hasSubst_of_constantCoeff_zero fun l => constantCoeff_X _ have hr : HasSubst (fun l : Fin g => (X (Sum.inr l) : MvPowerSeries (Fin g ⊕ Fin g) R)) := hasSubst_of_constantCoeff_zero fun l => constantCoeff_X _ have hU : ∀ j, (subst (fun l : Fin g => (X (Sum.inl l) : MvPowerSeries (Fin g ⊕ Fin g) R)) (φ.toPowerSeries j)).constantCoeff = 0 := fun j => constantCoeff_subst_eq_zero hl (fun l => constantCoeff_X _) (φ.constantCoeff_eq_zero j) have hV : ∀ j, (subst (fun l : Fin g => (X (Sum.inr l) : MvPowerSeries (Fin g ⊕ Fin g) R)) (φ.toPowerSeries j)).constantCoeff = 0 := fun j => constantCoeff_subst_eq_zero hr (fun l => constantCoeff_X _) (φ.constantCoeff_eq_zero j) have hxa : (fun l => adicEval J (Sum.elim x.val y.val) (X (Sum.inl l) : MvPowerSeries (Fin g ⊕ Fin g) R)) = x.val := funext fun l => adicEval_X _ _ _ have hyb : (fun l => adicEval J (Sum.elim x.val y.val) (X (Sum.inr l) : MvPowerSeries (Fin g ⊕ Fin g) R)) = y.val := funext fun l => adicEval_X _ _ _ have hin1 : (fun j => adicEval J (Sum.elim x.val y.val) (subst (fun l : Fin g => (X (Sum.inl l) : MvPowerSeries (Fin g ⊕ Fin g) R)) (φ.toPowerSeries j))) = fun j => adicEval J x.val (φ.toPowerSeries j) := by funext j rw [adicEval_subst J hw hl, hxa] have hin2 : (fun j => adicEval J (Sum.elim x.val y.val) (subst (fun l : Fin g => (X (Sum.inr l) : MvPowerSeries (Fin g ⊕ Fin g) R)) (φ.toPowerSeries j))) = fun j => adicEval J y.val (φ.toPowerSeries j) := by funext j rw [adicEval_subst J hw hr, hyb] have key := congrArg (adicEval J (Sum.elim x.val y.val)) (φ.subst_eq i) rw [adicEval_subst J hw F.hasSubst_toPowerSeries, adicEval_subst_elim G J hw hU hV, hin1, hin2] at key exact key) theorem val_evalPoints (φ : Hom F G) (x : Points F S J) (i : Fin h) : (φ.evalPoints x).val i = adicEval J x.val (φ.toPowerSeries i) := rfl theorem evalPoints_id (x : Points F S J) : (Hom.id F).evalPoints x = x := by ext i exact adicEval_X J x.val i theorem evalPoints_comp (ψ : Hom G H) (φ : Hom F G) (x : Points F S J) : (ψ.comp φ).evalPoints x = ψ.evalPoints (φ.evalPoints x) := by ext i exact adicEval_subst J x.mem_radical φ.hasSubst_toPowerSeries (ψ.toPowerSeries i) theorem evalPoints_zero (x : Points F S J) : (0 : Hom F G).evalPoints x = 0 := by ext i show adicEval J x.val (0 : MvPowerSeries (Fin g) R) = 0 rw [← coe_adicEvalAlgHom J x.mem_radical, map_zero] theorem evalPoints_add [IsComm G] (φ ψ : Hom F G) (x : Points F S J) : (φ + ψ).evalPoints x = φ.evalPoints x + ψ.evalPoints x := by ext i exact adicEval_subst_elim G J x.mem_radical φ.constantCoeff_eq_zero ψ.constantCoeff_eq_zero i theorem evalPoints_one (x : Points F S J) : Hom.evalPoints (1 : End F) x = x := evalPoints_id x theorem evalPoints_mul (φ ψ : End F) (x : Points F S J) : Hom.evalPoints (φ * ψ) x = Hom.evalPoints φ (Hom.evalPoints ψ x) := evalPoints_comp φ ψ x theorem evalPoints_natCast [IsComm F] (n : ℕ) (x : Points F S J) : Hom.evalPoints (n : End F) x = n • x := by ext i show adicEval J x.val (Hom.toPowerSeries (n : End F) i) = (n • x).val i rw [End.toPowerSeries_natCast F n, Points.val_nsmul] end Hom namespace Points variable {F : MvFormalGroup g R} {S : Type*} [CommRing S] [Algebra R S] {J : Ideal S} [IsAdicComplete J S] {S' : Type*} [CommRing S'] [Algebra R S'] {J' : Ideal S'} [IsAdicComplete J' S'] def map (φ : S →ₐ[R] S') (hJ : J.FG) (hφ : ∀ s ∈ J, φ s ∈ J'.radical) : Points F S J →+ Points F S' J' := AddMonoidHom.mk' (fun x => ⟨fun i => φ (x.val i), fun i => map_mem_radical φ hφ (x.mem_radical i)⟩) (fun x y => by ext i show φ (adicEval J (Sum.elim x.val y.val) (F.toPowerSeries i)) = adicEval J' (Sum.elim (fun j => φ (x.val j)) fun j => φ (y.val j)) (F.toPowerSeries i) have hfam : (fun s => φ (Sum.elim x.val y.val s)) = Sum.elim (fun j => φ (x.val j)) fun j => φ (y.val j) := by funext s rcases s with j | j <;> rfl rw [map_adicEval J J' φ hJ hφ (forall_sumElim x.mem_radical y.mem_radical), hfam]) theorem val_map (φ : S →ₐ[R] S') (hJ : J.FG) (hφ : ∀ s ∈ J, φ s ∈ J'.radical) (x : Points F S J) (i : Fin g) : (map φ hJ hφ x).val i = φ (x.val i) := rfl end Points namespace Hom variable {F : MvFormalGroup g R} {G : MvFormalGroup h R} {S : Type*} [CommRing S] [Algebra R S] {J : Ideal S} [IsAdicComplete J S] {S' : Type*} [CommRing S'] [Algebra R S'] {J' : Ideal S'} [IsAdicComplete J' S'] theorem evalPoints_map (ψ : Hom F G) (φ : S →ₐ[R] S') (hJ : J.FG) (hφ : ∀ s ∈ J, φ s ∈ J'.radical) (x : Points F S J) : ψ.evalPoints (Points.map φ hJ hφ x) = Points.map φ hJ hφ (ψ.evalPoints x) := by ext i exact (map_adicEval J J' φ hJ hφ x.mem_radical (ψ.toPowerSeries i)).symm end Hom end MvFormalGroup