import Mathlib set_option autoImplicit false open MvPowerSeries namespace MvPowerSeries.Restricted universe u v w variable {π“ž : Type u} [CommRing π“ž] {Οƒ : Type v} def Tendsto0 (p : β„•) (S : MvPowerSeries Οƒ π“ž) : Prop := βˆ€ N : β„•, βˆ€αΆ  m in Filter.cofinite, coeff m S ∈ Ideal.span {(p : π“ž) ^ N} namespace Tendsto0 variable {p : β„•} {S T : MvPowerSeries Οƒ π“ž} theorem finite_setOf (hS : Tendsto0 p S) (N : β„•) : {m : Οƒ β†’β‚€ β„• | coeff m S βˆ‰ Ideal.span {(p : π“ž) ^ N}}.Finite := Filter.eventually_cofinite.1 (hS N) noncomputable def bad (hS : Tendsto0 p S) (N : β„•) : Finset (Οƒ β†’β‚€ β„•) := (hS.finite_setOf N).toFinset theorem mem_bad_iff (hS : Tendsto0 p S) (N : β„•) (m : Οƒ β†’β‚€ β„•) : m ∈ hS.bad N ↔ coeff m S βˆ‰ Ideal.span {(p : π“ž) ^ N} := by simp [bad] theorem coeff_mem_of_not_mem_bad (hS : Tendsto0 p S) {N : β„•} {m : Οƒ β†’β‚€ β„•} (hm : m βˆ‰ hS.bad N) : coeff m S ∈ Ideal.span {(p : π“ž) ^ N} := by by_contra h exact hm ((hS.mem_bad_iff N m).2 h) theorem span_pow_le_span_pow {R : Type*} [CommRing R] (a : R) {M N : β„•} (h : M ≀ N) : Ideal.span {a ^ N} ≀ Ideal.span {a ^ M} := Ideal.span_singleton_le_span_singleton.2 (pow_dvd_pow a h) theorem bad_mono (hS : Tendsto0 p S) {M N : β„•} (h : M ≀ N) : hS.bad M βŠ† hS.bad N := by intro m hm rw [mem_bad_iff] at hm ⊒ exact fun h' => hm (span_pow_le_span_pow (p : π“ž) h h') theorem of_forall_eventually_eq_zero {S : MvPowerSeries Οƒ π“ž} (h : βˆ€αΆ  m in Filter.cofinite, coeff m S = 0) : Tendsto0 p S := by intro N filter_upwards [h] with m hm rw [hm] exact Ideal.zero_mem _ theorem zero : Tendsto0 p (0 : MvPowerSeries Οƒ π“ž) := of_forall_eventually_eq_zero (Filter.Eventually.of_forall fun m => by simp) theorem coe (P : MvPolynomial Οƒ π“ž) : Tendsto0 p (P : MvPowerSeries Οƒ π“ž) := by apply of_forall_eventually_eq_zero rw [Filter.eventually_cofinite] refine (P.support.finite_toSet).subset ?_ intro m hm by_contra h' apply hm rw [MvPolynomial.coeff_coe] exact MvPolynomial.notMem_support_iff.1 h' theorem one : Tendsto0 p (1 : MvPowerSeries Οƒ π“ž) := by have h := coe (p := p) (Οƒ := Οƒ) (π“ž := π“ž) 1 rwa [MvPolynomial.coe_one] at h theorem add (hS : Tendsto0 p S) (hT : Tendsto0 p T) : Tendsto0 p (S + T) := by intro N filter_upwards [hS N, hT N] with m hmS hmT rw [map_add] exact Ideal.add_mem _ hmS hmT theorem neg (hS : Tendsto0 p S) : Tendsto0 p (-S) := by intro N filter_upwards [hS N] with m hm rw [map_neg] exact (Ideal.neg_mem_iff _).2 hm theorem sub (hS : Tendsto0 p S) (hT : Tendsto0 p T) : Tendsto0 p (S - T) := by rw [sub_eq_add_neg]; exact hS.add hT.neg theorem smul (hS : Tendsto0 p S) (c : π“ž) : Tendsto0 p (c β€’ S) := by intro N filter_upwards [hS N] with m hm rw [map_smul, smul_eq_mul] exact Ideal.mul_mem_left _ c hm theorem exists_degree [Finite Οƒ] (hS : Tendsto0 p S) (N : β„•) : βˆƒ K : β„•, βˆ€ m : Οƒ β†’β‚€ β„•, K ≀ m.degree β†’ coeff m S ∈ Ideal.span {(p : π“ž) ^ N} := by classical refine ⟨(hS.bad N).sup (fun m => m.degree) + 1, fun m hm => ?_⟩ apply hS.coeff_mem_of_not_mem_bad intro hbad have := Finset.le_sup (f := fun m : Οƒ β†’β‚€ β„• => m.degree) hbad omega theorem of_degree [Finite Οƒ] {S : MvPowerSeries Οƒ π“ž} (h : βˆ€ N : β„•, βˆƒ K : β„•, βˆ€ m : Οƒ β†’β‚€ β„•, K ≀ m.degree β†’ coeff m S ∈ Ideal.span {(p : π“ž) ^ N}) : Tendsto0 p S := by classical intro N obtain ⟨K, hK⟩ := h N rw [Filter.eventually_cofinite] refine Set.Finite.subset (Finsupp.finite_of_degree_le (Οƒ := Οƒ) (n := K)) ?_ intro m hm by_contra h' simp only [Set.mem_setOf_eq, not_le] at h' exact hm (hK m h'.le) theorem mul [Finite Οƒ] (hS : Tendsto0 p S) (hT : Tendsto0 p T) : Tendsto0 p (S * T) := by classical apply of_degree intro N obtain ⟨K, hK⟩ := hS.exists_degree N obtain ⟨K', hK'⟩ := hT.exists_degree N refine ⟨K + K', fun e he => ?_⟩ rw [coeff_mul] refine Ideal.sum_mem _ fun x hx => ?_ rw [Finset.HasAntidiagonal.mem_antidiagonal] at hx have hdeg : x.1.degree + x.2.degree = e.degree := by rw [← map_add, hx] by_cases h1 : K ≀ x.1.degree Β· exact Ideal.mul_mem_right _ _ (hK _ h1) Β· have h2 : K' ≀ x.2.degree := by omega exact Ideal.mul_mem_left _ _ (hK' _ h2) theorem pow [Finite Οƒ] (hS : Tendsto0 p S) : βˆ€ n : β„•, Tendsto0 p (S ^ n) | 0 => by rw [pow_zero]; exact one | n + 1 => by rw [pow_succ]; exact (pow hS n).mul hS theorem prod [Finite Οƒ] {ΞΉ : Type*} (s : Finset ΞΉ) (f : ΞΉ β†’ MvPowerSeries Οƒ π“ž) (hf : βˆ€ i ∈ s, Tendsto0 p (f i)) : Tendsto0 p (∏ i ∈ s, f i) := by classical induction s using Finset.induction_on with | empty => rw [Finset.prod_empty]; exact one | insert a s ha ih => rw [Finset.prod_insert ha] exact (hf a (Finset.mem_insert_self a s)).mul (ih fun i hi => hf i (Finset.mem_insert_of_mem hi)) end Tendsto0 theorem tendsto0_X (p : β„•) (s : Οƒ) : Tendsto0 p (X s : MvPowerSeries Οƒ π“ž) := by have h := Tendsto0.coe (p := p) (MvPolynomial.X s : MvPolynomial Οƒ π“ž) rwa [MvPolynomial.coe_X] at h theorem tendsto0_C (p : β„•) (c : π“ž) : Tendsto0 p (C c : MvPowerSeries Οƒ π“ž) := by have h := Tendsto0.coe (p := p) (MvPolynomial.C c : MvPolynomial Οƒ π“ž) rwa [MvPolynomial.coe_C] at h theorem tendsto0_of_forall_coeff_mem_pow_degree [Finite Οƒ] (p : β„•) {S : MvPowerSeries Οƒ π“ž} (h : βˆ€ m, coeff m S ∈ Ideal.span {(p : π“ž) ^ m.degree}) : Tendsto0 p S := Tendsto0.of_degree fun N => ⟨N, fun m hm => Tendsto0.span_pow_le_span_pow (p : π“ž) hm (h m)⟩ section Eval variable (p : β„•) {Y : Type w} [CommRing Y] [Algebra π“ž Y] abbrev Cplt (Y : Type w) [CommRing Y] : Prop := IsAdicComplete (Ideal.span {(p : Y)}) Y def monom (x : Οƒ β†’ Y) (m : Οƒ β†’β‚€ β„•) : Y := m.prod fun s e => x s ^ e theorem monom_zero (x : Οƒ β†’ Y) : monom x 0 = 1 := by simp [monom] theorem monom_add (x : Οƒ β†’ Y) (m m' : Οƒ β†’β‚€ β„•) : monom x (m + m') = monom x m * monom x m' := by classical simp only [monom] rw [Finsupp.prod_add_index'] Β· intro s; exact pow_zero _ Β· intro s a b; exact pow_add _ _ _ noncomputable def psum (x : Οƒ β†’ Y) (T : Finset (Οƒ β†’β‚€ β„•)) (S : MvPowerSeries Οƒ π“ž) : Y := βˆ‘ m ∈ T, algebraMap π“ž Y (coeff m S) * monom x m theorem algebraMap_mem_span_pow {N : β„•} {c : π“ž} (hc : c ∈ Ideal.span {(p : π“ž) ^ N}) : algebraMap π“ž Y c ∈ Ideal.span {(p : Y) ^ N} := by rw [Ideal.mem_span_singleton] at hc ⊒ obtain ⟨d, rfl⟩ := hc refine ⟨algebraMap π“ž Y d, ?_⟩ rw [map_mul, map_pow, map_natCast] theorem psum_sub_psum_mem {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) {N : β„•} {T T' : Finset (Οƒ β†’β‚€ β„•)} (hT : hS.bad N βŠ† T) (hT' : hS.bad N βŠ† T') : psum x T S - psum x T' S ∈ Ideal.span {(p : Y) ^ N} := by classical have key : βˆ€ (A B : Finset (Οƒ β†’β‚€ β„•)), hS.bad N βŠ† B β†’ psum x A S - psum x (A ∩ B) S ∈ Ideal.span {(p : Y) ^ N} := by intro A B hB rw [psum, psum, ← Finset.sum_sdiff (Finset.inter_subset_left (s₁ := A) (sβ‚‚ := B)), add_sub_cancel_right] refine Ideal.sum_mem _ fun m hm => ?_ rw [Finset.mem_sdiff, Finset.mem_inter, not_and] at hm have hmB : m βˆ‰ hS.bad N := fun h => hm.2 hm.1 (hB h) exact Ideal.mul_mem_right _ _ (algebraMap_mem_span_pow p (hS.coeff_mem_of_not_mem_bad hmB)) have h1 := key T T' hT' have h2 := key T' T hT rw [Finset.inter_comm] at h2 have := Ideal.sub_mem _ h1 h2 rwa [sub_sub_sub_cancel_right] at this theorem smodEq_iff_sub_mem (N : β„•) (a b : Y) : a ≑ b [SMOD (Ideal.span {(p : Y)}) ^ N β€’ (⊀ : Submodule Y Y)] ↔ a - b ∈ Ideal.span {(p : Y) ^ N} := by rw [SModEq.sub_mem, Ideal.span_singleton_pow, smul_eq_mul, Ideal.mul_top] theorem eq_of_forall_sub_mem (hY : Cplt p Y) {a b : Y} (h : βˆ€ N : β„•, a - b ∈ Ideal.span {(p : Y) ^ N}) : a = b := by rw [← sub_eq_zero] refine IsHausdorff.haus hY.toIsHausdorff (a - b) fun N => ?_ rw [smodEq_iff_sub_mem, sub_zero] exact h N theorem exists_limit (hY : Cplt p Y) {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) : βˆƒ L : Y, βˆ€ N : β„•, L - psum x (hS.bad N) S ∈ Ideal.span {(p : Y) ^ N} := by have hprec := IsPrecomplete.prec hY.toIsPrecomplete (f := fun N => psum x (hS.bad N) S) ?_ Β· obtain ⟨L, hL⟩ := hprec refine ⟨L, fun N => ?_⟩ have h := (smodEq_iff_sub_mem p N _ _).1 (hL N) rw [← Ideal.neg_mem_iff, neg_sub] at h exact h Β· intro M N hMN rw [smodEq_iff_sub_mem] exact psum_sub_psum_mem p hS x subset_rfl (hS.bad_mono hMN) open Classical in noncomputable def evalT (hY : Cplt p Y) (x : Οƒ β†’ Y) (S : MvPowerSeries Οƒ π“ž) : Y := if hS : Tendsto0 p S then Classical.choose (exists_limit p hY hS x) else 0 variable (hY : Cplt p Y) include hY theorem evalT_sub_psum_bad_mem {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) (N : β„•) : evalT p hY x S - psum x (hS.bad N) S ∈ Ideal.span {(p : Y) ^ N} := by rw [evalT, dif_pos hS] exact Classical.choose_spec (exists_limit p hY hS x) N theorem evalT_sub_psum_mem {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) {N : β„•} {T : Finset (Οƒ β†’β‚€ β„•)} (hT : hS.bad N βŠ† T) : evalT p hY x S - psum x T S ∈ Ideal.span {(p : Y) ^ N} := by have h1 := evalT_sub_psum_bad_mem p hY hS x N have h2 := psum_sub_psum_mem p hS x subset_rfl hT have := Ideal.add_mem _ h1 h2 rwa [sub_add_sub_cancel] at this theorem evalT_mem_of_forall_coeff_mem {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) {N : β„•} (h : βˆ€ m, coeff m S ∈ Ideal.span {(p : π“ž) ^ N}) : evalT p hY x S ∈ Ideal.span {(p : Y) ^ N} := by have hbad : hS.bad N = βˆ… := by ext m simp only [Finset.notMem_empty, iff_false] rw [hS.mem_bad_iff] exact fun hm => hm (h m) have := evalT_sub_psum_bad_mem p hY hS x N rwa [hbad, psum, Finset.sum_empty, sub_zero] at this theorem evalT_congr_of_forall_sub_mem {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) {a : Y} (h : βˆ€ N : β„•, βˆƒ T : Finset (Οƒ β†’β‚€ β„•), hS.bad N βŠ† T ∧ a - psum x T S ∈ Ideal.span {(p : Y) ^ N}) : evalT p hY x S = a := by refine eq_of_forall_sub_mem p hY fun N => ?_ obtain ⟨T, hT, ha⟩ := h N have := Ideal.sub_mem _ (evalT_sub_psum_mem p hY hS x hT) ha rwa [sub_sub_sub_cancel_right] at this theorem evalT_coe (x : Οƒ β†’ Y) (P : MvPolynomial Οƒ π“ž) : evalT p hY x (P : MvPowerSeries Οƒ π“ž) = MvPolynomial.aeval x P := by classical apply evalT_congr_of_forall_sub_mem p hY (Tendsto0.coe P) x intro N refine ⟨(Tendsto0.coe (p := p) P).bad N βˆͺ P.support, Finset.subset_union_left, ?_⟩ have : psum x ((Tendsto0.coe (p := p) P).bad N βˆͺ P.support) (P : MvPowerSeries Οƒ π“ž) = MvPolynomial.aeval x P := by rw [psum, MvPolynomial.aeval_def, MvPolynomial.evalβ‚‚_eq, ← Finset.sum_subset Finset.subset_union_right] Β· refine Finset.sum_congr rfl fun m _ => ?_ rw [MvPolynomial.coeff_coe, monom, Finsupp.prod] Β· intro m _ hm rw [MvPolynomial.coeff_coe, MvPolynomial.notMem_support_iff.1 hm, map_zero, zero_mul] rw [this, sub_self] exact Ideal.zero_mem _ theorem evalT_add {S T : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (hT : Tendsto0 p T) (x : Οƒ β†’ Y) : evalT p hY x (S + T) = evalT p hY x S + evalT p hY x T := by classical apply evalT_congr_of_forall_sub_mem p hY (hS.add hT) x intro N refine ⟨(hS.add hT).bad N βˆͺ (hS.bad N βˆͺ hT.bad N), Finset.subset_union_left, ?_⟩ set U := (hS.add hT).bad N βˆͺ (hS.bad N βˆͺ hT.bad N) have hU : psum x U (S + T) = psum x U S + psum x U T := by simp only [psum, map_add, add_mul, Finset.sum_add_distrib] rw [hU, add_sub_add_comm] exact Ideal.add_mem _ (evalT_sub_psum_mem p hY hS x (Finset.subset_union_left.trans Finset.subset_union_right)) (evalT_sub_psum_mem p hY hT x (Finset.subset_union_right.trans Finset.subset_union_right)) theorem evalT_smul {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (c : π“ž) (x : Οƒ β†’ Y) : evalT p hY x (c β€’ S) = algebraMap π“ž Y c * evalT p hY x S := by classical apply evalT_congr_of_forall_sub_mem p hY (hS.smul c) x intro N refine ⟨(hS.smul c).bad N βˆͺ hS.bad N, Finset.subset_union_left, ?_⟩ have hU : psum x ((hS.smul c).bad N βˆͺ hS.bad N) (c β€’ S) = algebraMap π“ž Y c * psum x ((hS.smul c).bad N βˆͺ hS.bad N) S := by simp only [psum, map_smul, smul_eq_mul, map_mul, Finset.mul_sum, mul_assoc] rw [hU, ← mul_sub] exact Ideal.mul_mem_left _ _ (evalT_sub_psum_mem p hY hS x Finset.subset_union_right) theorem evalT_neg {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) : evalT p hY x (-S) = -evalT p hY x S := by have h := evalT_smul p hY hS (-1 : π“ž) x rwa [neg_one_smul, map_neg, map_one, neg_one_mul] at h theorem evalT_sub {S T : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (hT : Tendsto0 p T) (x : Οƒ β†’ Y) : evalT p hY x (S - T) = evalT p hY x S - evalT p hY x T := by rw [sub_eq_add_neg, evalT_add p hY hS hT.neg, evalT_neg p hY hT, sub_eq_add_neg] theorem evalT_zero (x : Οƒ β†’ Y) : evalT p hY x (0 : MvPowerSeries Οƒ π“ž) = 0 := by have h := evalT_coe p hY x (0 : MvPolynomial Οƒ π“ž) rwa [MvPolynomial.coe_zero, map_zero] at h theorem evalT_one (x : Οƒ β†’ Y) : evalT p hY x (1 : MvPowerSeries Οƒ π“ž) = 1 := by have h := evalT_coe p hY x (1 : MvPolynomial Οƒ π“ž) rwa [MvPolynomial.coe_one, map_one] at h theorem evalT_C (x : Οƒ β†’ Y) (c : π“ž) : evalT p hY x (C c : MvPowerSeries Οƒ π“ž) = algebraMap π“ž Y c := by have h := evalT_coe p hY x (MvPolynomial.C c : MvPolynomial Οƒ π“ž) rwa [MvPolynomial.coe_C, MvPolynomial.aeval_C] at h theorem evalT_X (x : Οƒ β†’ Y) (s : Οƒ) : evalT p hY x (X s : MvPowerSeries Οƒ π“ž) = x s := by have h := evalT_coe p hY x (MvPolynomial.X s : MvPolynomial Οƒ π“ž) rwa [MvPolynomial.coe_X, MvPolynomial.aeval_X] at h noncomputable def badPart {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (N : β„•) : MvPolynomial Οƒ π“ž := βˆ‘ m ∈ hS.bad N, MvPolynomial.monomial m (coeff m S) omit hY in theorem coeff_badPart [DecidableEq Οƒ] {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (N : β„•) (m : Οƒ β†’β‚€ β„•) : MvPolynomial.coeff m (badPart p hS N) = if m ∈ hS.bad N then coeff m S else 0 := by classical rw [badPart, MvPolynomial.coeff_sum] simp only [MvPolynomial.coeff_monomial] rw [Finset.sum_ite_eq'] omit hY in theorem coeff_sub_badPart_mem {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (N : β„•) (m : Οƒ β†’β‚€ β„•) : coeff m (S - (badPart p hS N : MvPowerSeries Οƒ π“ž)) ∈ Ideal.span {(p : π“ž) ^ N} := by classical rw [map_sub, MvPolynomial.coeff_coe, coeff_badPart] split_ifs with h Β· rw [sub_self]; exact Ideal.zero_mem _ Β· rw [sub_zero]; exact hS.coeff_mem_of_not_mem_bad h omit hY in theorem coeff_mul_mem_of_forall_left {I : Ideal π“ž} {S : MvPowerSeries Οƒ π“ž} (h : βˆ€ m, coeff m S ∈ I) (T : MvPowerSeries Οƒ π“ž) (e : Οƒ β†’β‚€ β„•) : coeff e (S * T) ∈ I := by classical rw [coeff_mul] exact Ideal.sum_mem _ fun x _ => Ideal.mul_mem_right _ _ (h x.1) omit hY in theorem coeff_mul_mem_of_forall_right {I : Ideal π“ž} (S : MvPowerSeries Οƒ π“ž) {T : MvPowerSeries Οƒ π“ž} (h : βˆ€ m, coeff m T ∈ I) (e : Οƒ β†’β‚€ β„•) : coeff e (S * T) ∈ I := by rw [mul_comm]; exact coeff_mul_mem_of_forall_left h S e theorem evalT_sub_aeval_badPart_mem {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) (N : β„•) : evalT p hY x S - MvPolynomial.aeval x (badPart p hS N) ∈ Ideal.span {(p : Y) ^ N} := by classical have hdec : S = (badPart p hS N : MvPowerSeries Οƒ π“ž) + (S - (badPart p hS N : MvPowerSeries Οƒ π“ž)) := by ring have h1 : evalT p hY x S = evalT p hY x (badPart p hS N : MvPowerSeries Οƒ π“ž) + evalT p hY x (S - (badPart p hS N : MvPowerSeries Οƒ π“ž)) := by conv_lhs => rw [hdec] exact evalT_add p hY (Tendsto0.coe _) (hS.sub (Tendsto0.coe _)) x rw [h1, evalT_coe, add_sub_cancel_left] exact evalT_mem_of_forall_coeff_mem p hY (hS.sub (Tendsto0.coe _)) x (coeff_sub_badPart_mem p hS N) theorem evalT_mul [Finite Οƒ] {S T : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (hT : Tendsto0 p T) (x : Οƒ β†’ Y) : evalT p hY x (S * T) = evalT p hY x S * evalT p hY x T := by classical refine eq_of_forall_sub_mem p hY fun N => ?_ set PS := badPart p hS N set PT := badPart p hT N set S' := S - (PS : MvPowerSeries Οƒ π“ž) set T' := T - (PT : MvPowerSeries Οƒ π“ž) have hS' : Tendsto0 p S' := hS.sub (Tendsto0.coe _) have hT' : Tendsto0 p T' := hT.sub (Tendsto0.coe _) have hcS' : βˆ€ m, coeff m S' ∈ Ideal.span {(p : π“ž) ^ N} := coeff_sub_badPart_mem p hS N have hcT' : βˆ€ m, coeff m T' ∈ Ideal.span {(p : π“ž) ^ N} := coeff_sub_badPart_mem p hT N have hdec : S * T = ((PS * PT : MvPolynomial Οƒ π“ž) : MvPowerSeries Οƒ π“ž) + ((PS : MvPowerSeries Οƒ π“ž) * T' + S' * T) := by simp only [S', T', MvPolynomial.coe_mul]; ring have hR : Tendsto0 p ((PS : MvPowerSeries Οƒ π“ž) * T' + S' * T) := ((Tendsto0.coe _).mul hT').add (hS'.mul hT) have hcR : βˆ€ m, coeff m ((PS : MvPowerSeries Οƒ π“ž) * T' + S' * T) ∈ Ideal.span {(p : π“ž) ^ N} := by intro m rw [map_add] exact Ideal.add_mem _ (coeff_mul_mem_of_forall_right _ hcT' m) (coeff_mul_mem_of_forall_left hcS' _ m) have h1 : evalT p hY x (S * T) = MvPolynomial.aeval x PS * MvPolynomial.aeval x PT + evalT p hY x ((PS : MvPowerSeries Οƒ π“ž) * T' + S' * T) := by rw [hdec, evalT_add p hY (Tendsto0.coe _) hR, evalT_coe, map_mul] have h2 := evalT_mem_of_forall_coeff_mem p hY hR x hcR have h3 := evalT_sub_aeval_badPart_mem p hY hS x N have h4 := evalT_sub_aeval_badPart_mem p hY hT x N have h5 : evalT p hY x S * evalT p hY x T - MvPolynomial.aeval x PS * MvPolynomial.aeval x PT ∈ Ideal.span {(p : Y) ^ N} := by have : evalT p hY x S * evalT p hY x T - MvPolynomial.aeval x PS * MvPolynomial.aeval x PT = (evalT p hY x S - MvPolynomial.aeval x PS) * evalT p hY x T + MvPolynomial.aeval x PS * (evalT p hY x T - MvPolynomial.aeval x PT) := by ring rw [this] exact Ideal.add_mem _ (Ideal.mul_mem_right _ _ h3) (Ideal.mul_mem_left _ _ h4) rw [h1] have : MvPolynomial.aeval x PS * MvPolynomial.aeval x PT + evalT p hY x ((PS : MvPowerSeries Οƒ π“ž) * T' + S' * T) - evalT p hY x S * evalT p hY x T = evalT p hY x ((PS : MvPowerSeries Οƒ π“ž) * T' + S' * T) - (evalT p hY x S * evalT p hY x T - MvPolynomial.aeval x PS * MvPolynomial.aeval x PT) := by ring rw [this] exact Ideal.sub_mem _ h2 h5 theorem evalT_pow [Finite Οƒ] {S : MvPowerSeries Οƒ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) : βˆ€ n : β„•, evalT p hY x (S ^ n) = evalT p hY x S ^ n | 0 => by rw [pow_zero, pow_zero, evalT_one] | n + 1 => by rw [pow_succ, pow_succ, evalT_mul p hY (hS.pow n) hS, evalT_pow hS x n] omit hY in theorem tendsto0_aeval [Finite Οƒ] {Ο„ : Type*} (a : Ο„ β†’ MvPowerSeries Οƒ π“ž) (ha : βˆ€ i, Tendsto0 p (a i)) (P : MvPolynomial Ο„ π“ž) : Tendsto0 p (MvPolynomial.aeval a P) := by classical induction P using MvPolynomial.induction_on with | C c => rw [MvPolynomial.aeval_C, Algebra.algebraMap_eq_smul_one] exact Tendsto0.one.smul c | add P Q hP hQ => rw [map_add]; exact hP.add hQ | mul_X P i hP => rw [map_mul, MvPolynomial.aeval_X]; exact hP.mul (ha i) theorem evalT_aeval [Finite Οƒ] {Ο„ : Type*} (a : Ο„ β†’ MvPowerSeries Οƒ π“ž) (ha : βˆ€ i, Tendsto0 p (a i)) (x : Οƒ β†’ Y) (P : MvPolynomial Ο„ π“ž) : evalT p hY x (MvPolynomial.aeval a P) = MvPolynomial.aeval (fun i => evalT p hY x (a i)) P := by classical induction P using MvPolynomial.induction_on with | C c => rw [MvPolynomial.aeval_C, MvPolynomial.aeval_C, Algebra.algebraMap_eq_smul_one, evalT_smul p hY Tendsto0.one, evalT_one, mul_one] | add P Q hP hQ => rw [map_add, map_add, evalT_add p hY (tendsto0_aeval p a ha P) (tendsto0_aeval p a ha Q), hP, hQ] | mul_X P i hP => rw [map_mul, MvPolynomial.aeval_X, map_mul, MvPolynomial.aeval_X, evalT_mul p hY (tendsto0_aeval p a ha P) (ha i), hP] omit hY in theorem tendsto0_subst [Finite Οƒ] {Ο„ : Type*} [Finite Ο„] {a : Ο„ β†’ MvPowerSeries Οƒ π“ž} (ha0 : βˆ€ i, constantCoeff (a i) = 0) (ha : βˆ€ i, Tendsto0 p (a i)) {S : MvPowerSeries Ο„ π“ž} (hS : Tendsto0 p S) : Tendsto0 p (subst a S) := by classical have has : HasSubst a := hasSubst_of_constantCoeff_zero ha0 intro N have hmon : βˆ€ d : Ο„ β†’β‚€ β„•, Tendsto0 p (d.prod fun s e => a s ^ e) := by intro d exact Tendsto0.prod _ _ fun s _ => (ha s).pow _ rw [Filter.eventually_cofinite] refine Set.Finite.subset ((hS.bad N).finite_toSet.biUnion fun d _ => (hmon d).finite_setOf N) ?_ intro e he simp only [Set.mem_setOf_eq] at he by_contra hcon apply he rw [coeff_subst has S e, finsum_eq_sum _ (coeff_subst_finite has S e)] refine Ideal.sum_mem _ fun d hd => ?_ by_cases hbad : d ∈ hS.bad N Β· have : coeff e (d.prod fun s e => a s ^ e) ∈ Ideal.span {(p : π“ž) ^ N} := by by_contra h' exact hcon (Set.mem_biUnion (Finset.mem_coe.2 hbad) h') rw [smul_eq_mul] exact Ideal.mul_mem_left _ _ this Β· rw [smul_eq_mul] exact Ideal.mul_mem_right _ _ (hS.coeff_mem_of_not_mem_bad hbad) omit hY in theorem coeff_subst_mem_of_forall {Ο„ : Type*} {a : Ο„ β†’ MvPowerSeries Οƒ π“ž} (has : HasSubst a) {I : Ideal π“ž} {S : MvPowerSeries Ο„ π“ž} (h : βˆ€ d, coeff d S ∈ I) (e : Οƒ β†’β‚€ β„•) : coeff e (subst a S) ∈ I := by classical rw [coeff_subst has S e, finsum_eq_sum _ (coeff_subst_finite has S e)] refine Ideal.sum_mem _ fun d _ => ?_ rw [smul_eq_mul] exact Ideal.mul_mem_right _ _ (h d) theorem evalT_subst [Finite Οƒ] {Ο„ : Type*} [Finite Ο„] {a : Ο„ β†’ MvPowerSeries Οƒ π“ž} (ha0 : βˆ€ i, constantCoeff (a i) = 0) (ha : βˆ€ i, Tendsto0 p (a i)) {S : MvPowerSeries Ο„ π“ž} (hS : Tendsto0 p S) (x : Οƒ β†’ Y) : evalT p hY x (subst a S) = evalT p hY (fun i => evalT p hY x (a i)) S := by classical have has : HasSubst a := hasSubst_of_constantCoeff_zero ha0 refine eq_of_forall_sub_mem p hY fun N => ?_ set P := badPart p hS N set S' := S - (P : MvPowerSeries Ο„ π“ž) have hS' : Tendsto0 p S' := hS.sub (Tendsto0.coe _) have hdec : S = (P : MvPowerSeries Ο„ π“ž) + S' := by simp only [S']; ring have hsub : subst a S = MvPolynomial.aeval a P + subst a S' := by conv_lhs => rw [hdec] rw [subst_add has, subst_coe] have hS'sub : Tendsto0 p (subst a S') := tendsto0_subst p ha0 ha hS' have h1 : evalT p hY x (subst a S) = MvPolynomial.aeval (fun i => evalT p hY x (a i)) P + evalT p hY x (subst a S') := by rw [hsub, evalT_add p hY (tendsto0_aeval p a ha P) hS'sub, evalT_aeval p hY a ha] have h2 : evalT p hY x (subst a S') ∈ Ideal.span {(p : Y) ^ N} := evalT_mem_of_forall_coeff_mem p hY hS'sub x (coeff_subst_mem_of_forall has (coeff_sub_badPart_mem p hS N)) have h3 := evalT_sub_aeval_badPart_mem p hY hS (fun i => evalT p hY x (a i)) N rw [h1] have : MvPolynomial.aeval (fun i => evalT p hY x (a i)) P + evalT p hY x (subst a S') - evalT p hY (fun i => evalT p hY x (a i)) S = evalT p hY x (subst a S') - (evalT p hY (fun i => evalT p hY x (a i)) S - MvPolynomial.aeval (fun i => evalT p hY x (a i)) P) := by ring rw [this] exact Ideal.sub_mem _ h2 h3 end Eval end MvPowerSeries.Restricted