l3lab/ntp-mathlib huggingface dataset:
/-- A ring `R` that is `I`-adically complete is Henselian at `I`. -/
instance (priority := 100) IsAdicComplete.henselianRing (R : Type*) [CommRing R] (I : Ideal R)
    [IsAdicComplete I R] : HenselianRing R I where
  jac := IsAdicComplete.le_jacobson_bot _
  is_henselian := by
    intro f _ a₀ h₁ h₂
    classical
      let f' := derivative f
      -- we define a sequence `c n` by starting at `a₀` and then continually
      -- applying the function sending `b` to `b - f(b)/f'(b)` (Newton's method).
      -- Note that `f'.eval b` is a unit, because `b` has the same residue as `a₀` modulo `I`.
      let c : ℕ → R := fun n => Nat.recOn n a₀ fun _ b => b - f.eval b * Ring.inverse (f'.eval b)
      have hc : ∀ n, c (n + 1) = c n - f.eval (c n) * Ring.inverse (f'.eval (c n)) := by
        intro n
        simp only [Nat.rec_add_one]
      -- we now spend some time determining properties of the sequence `c : ℕ → R`
      -- `hc_mod`: for every `n`, we have `c n ≡ a₀ [SMOD I]`
      -- `hf'c`  : for every `n`, `f'.eval (c n)` is a unit
      -- `hfcI`  : for every `n`, `f.eval (c n)` is contained in `I ^ (n+1)`
      have hc_mod : ∀ n, c n ≡ a₀ [SMOD I] := by
        intro n
        induction' n with n ih
        · rfl
        rw [Nat.succ_eq_add_one, hc, sub_eq_add_neg, ← add_zero a₀]
        refine' ih.add _
        rw [SModEq.zero, Ideal.neg_mem_iff]
        refine' I.mul_mem_right _ _
        rw [← SModEq.zero] at h₁ ⊢
        exact (ih.eval f).trans h₁
      have hf'c : ∀ n, IsUnit (f'.eval (c n)) := by
        intro n
        haveI := isLocalRingHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I)
        apply isUnit_of_map_unit (Ideal.Quotient.mk I)
        convert h₂ using 1
        exact SModEq.def.mp ((hc_mod n).eval _)
      have hfcI : ∀ n, f.eval (c n) ∈ I ^ (n + 1) := by
        intro n
        induction' n with n ih
        · 

Proof state:
case zero
R : Type u_1
inst✝¹ : CommRing R
I : Ideal R
inst✝ : IsAdicComplete I R
f : R[X]
x✝ : Monic f
a₀ : R
h₁ : Polynomial.eval a₀ f ∈ I
h₂ : IsUnit ((Ideal.Quotient.mk I) (Polynomial.eval a₀ (derivative f)))
f' : R[X] := derivative f
c : ℕ → R := fun n => Nat.recOn n a₀ fun x b => b - Polynomial.eval b f * Ring.inverse (Polynomial.eval b f')
hc : ∀ (n : ℕ), c (n + 1) = c n - Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f')
hc_mod : ∀ (n : ℕ), c n ≡ a₀ [SMOD I]
hf'c : ∀ (n : ℕ), IsUnit (Polynomial.eval (c n) f')
⊢ Polynomial.eval (c Nat.zero) f ∈ I ^ (Nat.zero + 1)

Next tactic:
simpa only [Nat.zero_eq, Nat.rec_zero, zero_add, pow_one] using h₁
/-- A ring `R` that is `I`-adically complete is Henselian at `I`. -/
instance (priority := 100) IsAdicComplete.henselianRing (R : Type*) [CommRing R] (I : Ideal R)
    [IsAdicComplete I R] : HenselianRing R I where
  jac := IsAdicComplete.le_jacobson_bot _
  is_henselian := by
    intro f _ a₀ h₁ h₂
    classical
      let f' := derivative f
      -- we define a sequence `c n` by starting at `a₀` and then continually
      -- applying the function sending `b` to `b - f(b)/f'(b)` (Newton's method).
      -- Note that `f'.eval b` is a unit, because `b` has the same residue as `a₀` modulo `I`.
      let c : ℕ → R := fun n => Nat.recOn n a₀ fun _ b => b - f.eval b * Ring.inverse (f'.eval b)
      have hc : ∀ n, c (n + 1) = c n - f.eval (c n) * Ring.inverse (f'.eval (c n)) := by
        intro n
        simp only [Nat.rec_add_one]
      -- we now spend some time determining properties of the sequence `c : ℕ → R`
      -- `hc_mod`: for every `n`, we have `c n ≡ a₀ [SMOD I]`
      -- `hf'c`  : for every `n`, `f'.eval (c n)` is a unit
      -- `hfcI`  : for every `n`, `f.eval (c n)` is contained in `I ^ (n+1)`
      have hc_mod : ∀ n, c n ≡ a₀ [SMOD I] := by
        intro n
        induction' n with n ih
        · rfl
        rw [Nat.succ_eq_add_one, hc, sub_eq_add_neg, ← add_zero a₀]
        refine' ih.add _
        rw [SModEq.zero, Ideal.neg_mem_iff]
        refine' I.mul_mem_right _ _
        rw [← SModEq.zero] at h₁ ⊢
        exact (ih.eval f).trans h₁
      have hf'c : ∀ n, IsUnit (f'.eval (c n)) := by
        intro n
        haveI := isLocalRingHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I)
        apply isUnit_of_map_unit (Ideal.Quotient.mk I)
        convert h₂ using 1
        exact SModEq.def.mp ((hc_mod n).eval _)
      have hfcI : ∀ n, f.eval (c n) ∈ I ^ (n + 1) := by
        intro n
        induction' n with n ih
        · simpa only [Nat.zero_eq, Nat.rec_zero, zero_add, pow_one] using h₁
        

Proof state:
case succ
R : Type u_1
inst✝¹ : CommRing R
I : Ideal R
inst✝ : IsAdicComplete I R
f : R[X]
x✝ : Monic f
a₀ : R
h₁ : Polynomial.eval a₀ f ∈ I
h₂ : IsUnit ((Ideal.Quotient.mk I) (Polynomial.eval a₀ (derivative f)))
f' : R[X] := derivative f
c : ℕ → R := fun n => Nat.recOn n a₀ fun x b => b - Polynomial.eval b f * Ring.inverse (Polynomial.eval b f')
hc : ∀ (n : ℕ), c (n + 1) = c n - Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f')
hc_mod : ∀ (n : ℕ), c n ≡ a₀ [SMOD I]
hf'c : ∀ (n : ℕ), IsUnit (Polynomial.eval (c n) f')
n : ℕ
ih : Polynomial.eval (c n) f ∈ I ^ (n + 1)
⊢ Polynomial.eval (c (Nat.succ n)) f ∈ I ^ (Nat.succ n + 1)

Next tactic:
rw [Nat.succ_eq_add_one, ← taylor_eval_sub (c n), hc, sub_eq_add_neg, sub_eq_add_neg,
          add_neg_cancel_comm]
/-- A ring `R` that is `I`-adically complete is Henselian at `I`. -/
instance (priority := 100) IsAdicComplete.henselianRing (R : Type*) [CommRing R] (I : Ideal R)
    [IsAdicComplete I R] : HenselianRing R I where
  jac := IsAdicComplete.le_jacobson_bot _
  is_henselian := by
    intro f _ a₀ h₁ h₂
    classical
      let f' := derivative f
      -- we define a sequence `c n` by starting at `a₀` and then continually
      -- applying the function sending `b` to `b - f(b)/f'(b)` (Newton's method).
      -- Note that `f'.eval b` is a unit, because `b` has the same residue as `a₀` modulo `I`.
      let c : ℕ → R := fun n => Nat.recOn n a₀ fun _ b => b - f.eval b * Ring.inverse (f'.eval b)
      have hc : ∀ n, c (n + 1) = c n - f.eval (c n) * Ring.inverse (f'.eval (c n)) := by
        intro n
        simp only [Nat.rec_add_one]
      -- we now spend some time determining properties of the sequence `c : ℕ → R`
      -- `hc_mod`: for every `n`, we have `c n ≡ a₀ [SMOD I]`
      -- `hf'c`  : for every `n`, `f'.eval (c n)` is a unit
      -- `hfcI`  : for every `n`, `f.eval (c n)` is contained in `I ^ (n+1)`
      have hc_mod : ∀ n, c n ≡ a₀ [SMOD I] := by
        intro n
        induction' n with n ih
        · rfl
        rw [Nat.succ_eq_add_one, hc, sub_eq_add_neg, ← add_zero a₀]
        refine' ih.add _
        rw [SModEq.zero, Ideal.neg_mem_iff]
        refine' I.mul_mem_right _ _
        rw [← SModEq.zero] at h₁ ⊢
        exact (ih.eval f).trans h₁
      have hf'c : ∀ n, IsUnit (f'.eval (c n)) := by
        intro n
        haveI := isLocalRingHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I)
        apply isUnit_of_map_unit (Ideal.Quotient.mk I)
        convert h₂ using 1
        exact SModEq.def.mp ((hc_mod n).eval _)
      have hfcI : ∀ n, f.eval (c n) ∈ I ^ (n + 1) := by
        intro n
        induction' n with n ih
        · simpa only [Nat.zero_eq, Nat.rec_zero, zero_add, pow_one] using h₁
        rw [Nat.succ_eq_add_one, ← taylor_eval_sub (c n), hc, sub_eq_add_neg, sub_eq_add_neg,
          add_neg_cancel_comm]
        

Proof state:
case succ
R : Type u_1
inst✝¹ : CommRing R
I : Ideal R
inst✝ : IsAdicComplete I R
f : R[X]
x✝ : Monic f
a₀ : R
h₁ : Polynomial.eval a₀ f ∈ I
h₂ : IsUnit ((Ideal.Quotient.mk I) (Polynomial.eval a₀ (derivative f)))
f' : R[X] := derivative f
c : ℕ → R := fun n => Nat.recOn n a₀ fun x b => b - Polynomial.eval b f * Ring.inverse (Polynomial.eval b f')
hc : ∀ (n : ℕ), c (n + 1) = c n - Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f')
hc_mod : ∀ (n : ℕ), c n ≡ a₀ [SMOD I]
hf'c : ∀ (n : ℕ), IsUnit (Polynomial.eval (c n) f')
n : ℕ
ih : Polynomial.eval (c n) f ∈ I ^ (n + 1)
⊢ Polynomial.eval (-(Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f'))) ((taylor (c n)) f) ∈
    I ^ (n + 1 + 1)

Next tactic:
rw [eval_eq_sum, sum_over_range' _ _ _ (lt_add_of_pos_right _ zero_lt_two), ←
          Finset.sum_range_add_sum_Ico _ (Nat.le_add_left _ _)]
/-- A ring `R` that is `I`-adically complete is Henselian at `I`. -/
instance (priority := 100) IsAdicComplete.henselianRing (R : Type*) [CommRing R] (I : Ideal R)
    [IsAdicComplete I R] : HenselianRing R I where
  jac := IsAdicComplete.le_jacobson_bot _
  is_henselian := by
    intro f _ a₀ h₁ h₂
    classical
      let f' := derivative f
      -- we define a sequence `c n` by starting at `a₀` and then continually
      -- applying the function sending `b` to `b - f(b)/f'(b)` (Newton's method).
      -- Note that `f'.eval b` is a unit, because `b` has the same residue as `a₀` modulo `I`.
      let c : ℕ → R := fun n => Nat.recOn n a₀ fun _ b => b - f.eval b * Ring.inverse (f'.eval b)
      have hc : ∀ n, c (n + 1) = c n - f.eval (c n) * Ring.inverse (f'.eval (c n)) := by
        intro n
        simp only [Nat.rec_add_one]
      -- we now spend some time determining properties of the sequence `c : ℕ → R`
      -- `hc_mod`: for every `n`, we have `c n ≡ a₀ [SMOD I]`
      -- `hf'c`  : for every `n`, `f'.eval (c n)` is a unit
      -- `hfcI`  : for every `n`, `f.eval (c n)` is contained in `I ^ (n+1)`
      have hc_mod : ∀ n, c n ≡ a₀ [SMOD I] := by
        intro n
        induction' n with n ih
        · rfl
        rw [Nat.succ_eq_add_one, hc, sub_eq_add_neg, ← add_zero a₀]
        refine' ih.add _
        rw [SModEq.zero, Ideal.neg_mem_iff]
        refine' I.mul_mem_right _ _
        rw [← SModEq.zero] at h₁ ⊢
        exact (ih.eval f).trans h₁
      have hf'c : ∀ n, IsUnit (f'.eval (c n)) := by
        intro n
        haveI := isLocalRingHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I)
        apply isUnit_of_map_unit (Ideal.Quotient.mk I)
        convert h₂ using 1
        exact SModEq.def.mp ((hc_mod n).eval _)
      have hfcI : ∀ n, f.eval (c n) ∈ I ^ (n + 1) := by
        intro n
        induction' n with n ih
        · simpa only [Nat.zero_eq, Nat.rec_zero, zero_add, pow_one] using h₁
        rw [Nat.succ_eq_add_one, ← taylor_eval_sub (c n), hc, sub_eq_add_neg, sub_eq_add_neg,
          add_neg_cancel_comm]
        rw [eval_eq_sum, sum_over_range' _ _ _ (lt_add_of_pos_right _ zero_lt_two), ←
          Finset.sum_range_add_sum_Ico _ (Nat.le_add_left _ _)]
        swap
        · 

Proof state:
R : Type u_1
inst✝¹ : CommRing R
I : Ideal R
inst✝ : IsAdicComplete I R
f : R[X]
x✝ : Monic f
a₀ : R
h₁ : Polynomial.eval a₀ f ∈ I
h₂ : IsUnit ((Ideal.Quotient.mk I) (Polynomial.eval a₀ (derivative f)))
f' : R[X] := derivative f
c : ℕ → R := fun n => Nat.recOn n a₀ fun x b => b - Polynomial.eval b f * Ring.inverse (Polynomial.eval b f')
hc : ∀ (n : ℕ), c (n + 1) = c n - Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f')
hc_mod : ∀ (n : ℕ), c n ≡ a₀ [SMOD I]
hf'c : ∀ (n : ℕ), IsUnit (Polynomial.eval (c n) f')
n : ℕ
ih : Polynomial.eval (c n) f ∈ I ^ (n + 1)
⊢ ∀ (n_1 : ℕ), 0 * (-(Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f'))) ^ n_1 = 0

Next tactic:
intro i
/-- A ring `R` that is `I`-adically complete is Henselian at `I`. -/
instance (priority := 100) IsAdicComplete.henselianRing (R : Type*) [CommRing R] (I : Ideal R)
    [IsAdicComplete I R] : HenselianRing R I where
  jac := IsAdicComplete.le_jacobson_bot _
  is_henselian := by
    intro f _ a₀ h₁ h₂
    classical
      let f' := derivative f
      -- we define a sequence `c n` by starting at `a₀` and then continually
      -- applying the function sending `b` to `b - f(b)/f'(b)` (Newton's method).
      -- Note that `f'.eval b` is a unit, because `b` has the same residue as `a₀` modulo `I`.
      let c : ℕ → R := fun n => Nat.recOn n a₀ fun _ b => b - f.eval b * Ring.inverse (f'.eval b)
      have hc : ∀ n, c (n + 1) = c n - f.eval (c n) * Ring.inverse (f'.eval (c n)) := by
        intro n
        simp only [Nat.rec_add_one]
      -- we now spend some time determining properties of the sequence `c : ℕ → R`
      -- `hc_mod`: for every `n`, we have `c n ≡ a₀ [SMOD I]`
      -- `hf'c`  : for every `n`, `f'.eval (c n)` is a unit
      -- `hfcI`  : for every `n`, `f.eval (c n)` is contained in `I ^ (n+1)`
      have hc_mod : ∀ n, c n ≡ a₀ [SMOD I] := by
        intro n
        induction' n with n ih
        · rfl
        rw [Nat.succ_eq_add_one, hc, sub_eq_add_neg, ← add_zero a₀]
        refine' ih.add _
        rw [SModEq.zero, Ideal.neg_mem_iff]
        refine' I.mul_mem_right _ _
        rw [← SModEq.zero] at h₁ ⊢
        exact (ih.eval f).trans h₁
      have hf'c : ∀ n, IsUnit (f'.eval (c n)) := by
        intro n
        haveI := isLocalRingHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I)
        apply isUnit_of_map_unit (Ideal.Quotient.mk I)
        convert h₂ using 1
        exact SModEq.def.mp ((hc_mod n).eval _)
      have hfcI : ∀ n, f.eval (c n) ∈ I ^ (n + 1) := by
        intro n
        induction' n with n ih
        · simpa only [Nat.zero_eq, Nat.rec_zero, zero_add, pow_one] using h₁
        rw [Nat.succ_eq_add_one, ← taylor_eval_sub (c n), hc, sub_eq_add_neg, sub_eq_add_neg,
          add_neg_cancel_comm]
        rw [eval_eq_sum, sum_over_range' _ _ _ (lt_add_of_pos_right _ zero_lt_two), ←
          Finset.sum_range_add_sum_Ico _ (Nat.le_add_left _ _)]
        swap
        · intro i
          

Proof state:
R : Type u_1
inst✝¹ : CommRing R
I : Ideal R
inst✝ : IsAdicComplete I R
f : R[X]
x✝ : Monic f
a₀ : R
h₁ : Polynomial.eval a₀ f ∈ I
h₂ : IsUnit ((Ideal.Quotient.mk I) (Polynomial.eval a₀ (derivative f)))
f' : R[X] := derivative f
c : ℕ → R := fun n => Nat.recOn n a₀ fun x b => b - Polynomial.eval b f * Ring.inverse (Polynomial.eval b f')
hc : ∀ (n : ℕ), c (n + 1) = c n - Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f')
hc_mod : ∀ (n : ℕ), c n ≡ a₀ [SMOD I]
hf'c : ∀ (n : ℕ), IsUnit (Polynomial.eval (c n) f')
n : ℕ
ih : Polynomial.eval (c n) f ∈ I ^ (n + 1)
i : ℕ
⊢ 0 * (-(Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f'))) ^ i = 0

Next tactic:
rw [zero_mul]
/-- A ring `R` that is `I`-adically complete is Henselian at `I`. -/
instance (priority := 100) IsAdicComplete.henselianRing (R : Type*) [CommRing R] (I : Ideal R)
    [IsAdicComplete I R] : HenselianRing R I where
  jac := IsAdicComplete.le_jacobson_bot _
  is_henselian := by
    intro f _ a₀ h₁ h₂
    classical
      let f' := derivative f
      -- we define a sequence `c n` by starting at `a₀` and then continually
      -- applying the function sending `b` to `b - f(b)/f'(b)` (Newton's method).
      -- Note that `f'.eval b` is a unit, because `b` has the same residue as `a₀` modulo `I`.
      let c : ℕ → R := fun n => Nat.recOn n a₀ fun _ b => b - f.eval b * Ring.inverse (f'.eval b)
      have hc : ∀ n, c (n + 1) = c n - f.eval (c n) * Ring.inverse (f'.eval (c n)) := by
        intro n
        simp only [Nat.rec_add_one]
      -- we now spend some time determining properties of the sequence `c : ℕ → R`
      -- `hc_mod`: for every `n`, we have `c n ≡ a₀ [SMOD I]`
      -- `hf'c`  : for every `n`, `f'.eval (c n)` is a unit
      -- `hfcI`  : for every `n`, `f.eval (c n)` is contained in `I ^ (n+1)`
      have hc_mod : ∀ n, c n ≡ a₀ [SMOD I] := by
        intro n
        induction' n with n ih
        · rfl
        rw [Nat.succ_eq_add_one, hc, sub_eq_add_neg, ← add_zero a₀]
        refine' ih.add _
        rw [SModEq.zero, Ideal.neg_mem_iff]
        refine' I.mul_mem_right _ _
        rw [← SModEq.zero] at h₁ ⊢
        exact (ih.eval f).trans h₁
      have hf'c : ∀ n, IsUnit (f'.eval (c n)) := by
        intro n
        haveI := isLocalRingHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I)
        apply isUnit_of_map_unit (Ideal.Quotient.mk I)
        convert h₂ using 1
        exact SModEq.def.mp ((hc_mod n).eval _)
      have hfcI : ∀ n, f.eval (c n) ∈ I ^ (n + 1) := by
        intro n
        induction' n with n ih
        · simpa only [Nat.zero_eq, Nat.rec_zero, zero_add, pow_one] using h₁
        rw [Nat.succ_eq_add_one, ← taylor_eval_sub (c n), hc, sub_eq_add_neg, sub_eq_add_neg,
          add_neg_cancel_comm]
        rw [eval_eq_sum, sum_over_range' _ _ _ (lt_add_of_pos_right _ zero_lt_two), ←
          Finset.sum_range_add_sum_Ico _ (Nat.le_add_left _ _)]
        swap
        · intro i
          rw [zero_mul]
        refine' Ideal.add_mem _ _ _
        · 

Proof state:
case succ.refine'_1
R : Type u_1
inst✝¹ : CommRing R
I : Ideal R
inst✝ : IsAdicComplete I R
f : R[X]
x✝ : Monic f
a₀ : R
h₁ : Polynomial.eval a₀ f ∈ I
h₂ : IsUnit ((Ideal.Quotient.mk I) (Polynomial.eval a₀ (derivative f)))
f' : R[X] := derivative f
c : ℕ → R := fun n => Nat.recOn n a₀ fun x b => b - Polynomial.eval b f * Ring.inverse (Polynomial.eval b f')
hc : ∀ (n : ℕ), c (n + 1) = c n - Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f')
hc_mod : ∀ (n : ℕ), c n ≡ a₀ [SMOD I]
hf'c : ∀ (n : ℕ), IsUnit (Polynomial.eval (c n) f')
n : ℕ
ih : Polynomial.eval (c n) f ∈ I ^ (n + 1)
⊢ ∑ k in Finset.range 2,
      coeff ((taylor (c n)) f) k * (-(Polynomial.eval (c n) f * Ring.inverse (Polynomial.eval (c n) f'))) ^ k ∈
    I ^ (n + 1 + 1)

Next tactic:
erw [Finset.sum_range_succ]
/-- The constructed fan is indeed a limit -/
def piFanIsLimit {ι : Type v} (α : ι → TopCatMax.{v, u}) : IsLimit (piFan α) where
  lift S :=
    { toFun := fun s i => S.π.app ⟨i⟩ s
      continuous_toFun := continuous_pi (fun i => (S.π.app ⟨i⟩).2) }
  uniq := by
    

Proof state:
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
⊢ ∀ (s : Cone (Discrete.functor α)) (m : s.pt ⟶ (piFan α).pt),
    (∀ (j : Discrete ι), m ≫ (piFan α).π.app j = s.π.app j) →
      m = (fun S => ContinuousMap.mk fun s i => (S.π.app { as := i }) s) s

Next tactic:
intro S m h
/-- The constructed fan is indeed a limit -/
def piFanIsLimit {ι : Type v} (α : ι → TopCatMax.{v, u}) : IsLimit (piFan α) where
  lift S :=
    { toFun := fun s i => S.π.app ⟨i⟩ s
      continuous_toFun := continuous_pi (fun i => (S.π.app ⟨i⟩).2) }
  uniq := by
    intro S m h
    

Proof state:
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
S : Cone (Discrete.functor α)
m : S.pt ⟶ (piFan α).pt
h : ∀ (j : Discrete ι), m ≫ (piFan α).π.app j = S.π.app j
⊢ m = (fun S => ContinuousMap.mk fun s i => (S.π.app { as := i }) s) S

Next tactic:
apply ContinuousMap.ext
/-- The constructed fan is indeed a limit -/
def piFanIsLimit {ι : Type v} (α : ι → TopCatMax.{v, u}) : IsLimit (piFan α) where
  lift S :=
    { toFun := fun s i => S.π.app ⟨i⟩ s
      continuous_toFun := continuous_pi (fun i => (S.π.app ⟨i⟩).2) }
  uniq := by
    intro S m h
    apply ContinuousMap.ext; 

Proof state:
case h
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
S : Cone (Discrete.functor α)
m : S.pt ⟶ (piFan α).pt
h : ∀ (j : Discrete ι), m ≫ (piFan α).π.app j = S.π.app j
⊢ ∀ (a : ↑S.pt), m a = ((fun S => ContinuousMap.mk fun s i => (S.π.app { as := i }) s) S) a

Next tactic:
intro x
/-- The constructed fan is indeed a limit -/
def piFanIsLimit {ι : Type v} (α : ι → TopCatMax.{v, u}) : IsLimit (piFan α) where
  lift S :=
    { toFun := fun s i => S.π.app ⟨i⟩ s
      continuous_toFun := continuous_pi (fun i => (S.π.app ⟨i⟩).2) }
  uniq := by
    intro S m h
    apply ContinuousMap.ext; intro x
    

Proof state:
case h
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
S : Cone (Discrete.functor α)
m : S.pt ⟶ (piFan α).pt
h : ∀ (j : Discrete ι), m ≫ (piFan α).π.app j = S.π.app j
x : ↑S.pt
⊢ m x = ((fun S => ContinuousMap.mk fun s i => (S.π.app { as := i }) s) S) x

Next tactic:
funext i
/-- The constructed fan is indeed a limit -/
def piFanIsLimit {ι : Type v} (α : ι → TopCatMax.{v, u}) : IsLimit (piFan α) where
  lift S :=
    { toFun := fun s i => S.π.app ⟨i⟩ s
      continuous_toFun := continuous_pi (fun i => (S.π.app ⟨i⟩).2) }
  uniq := by
    intro S m h
    apply ContinuousMap.ext; intro x
    funext i
    

Proof state:
case h.h
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
S : Cone (Discrete.functor α)
m : S.pt ⟶ (piFan α).pt
h : ∀ (j : Discrete ι), m ≫ (piFan α).π.app j = S.π.app j
x : ↑S.pt
i : ι
⊢ m x i = ((fun S => ContinuousMap.mk fun s i => (S.π.app { as := i }) s) S) x i

Next tactic:
dsimp
/-- The constructed fan is indeed a limit -/
def piFanIsLimit {ι : Type v} (α : ι → TopCatMax.{v, u}) : IsLimit (piFan α) where
  lift S :=
    { toFun := fun s i => S.π.app ⟨i⟩ s
      continuous_toFun := continuous_pi (fun i => (S.π.app ⟨i⟩).2) }
  uniq := by
    intro S m h
    apply ContinuousMap.ext; intro x
    funext i
    dsimp
    

Proof state:
case h.h
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
S : Cone (Discrete.functor α)
m : S.pt ⟶ (piFan α).pt
h : ∀ (j : Discrete ι), m ≫ (piFan α).π.app j = S.π.app j
x : ↑S.pt
i : ι
⊢ m x i = (ContinuousMap.mk fun s i => (S.π.app { as := i }) s) x i

Next tactic:
rw [ContinuousMap.coe_mk, ← h ⟨i⟩]
/-- The constructed fan is indeed a limit -/
def piFanIsLimit {ι : Type v} (α : ι → TopCatMax.{v, u}) : IsLimit (piFan α) where
  lift S :=
    { toFun := fun s i => S.π.app ⟨i⟩ s
      continuous_toFun := continuous_pi (fun i => (S.π.app ⟨i⟩).2) }
  uniq := by
    intro S m h
    apply ContinuousMap.ext; intro x
    funext i
    dsimp
    rw [ContinuousMap.coe_mk, ← h ⟨i⟩]
    

Proof state:
case h.h
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
S : Cone (Discrete.functor α)
m : S.pt ⟶ (piFan α).pt
h : ∀ (j : Discrete ι), m ≫ (piFan α).π.app j = S.π.app j
x : ↑S.pt
i : ι
⊢ m x i = (m ≫ (piFan α).π.app { as := i }) x

Next tactic:
rfl
@[reassoc (attr := simp)]
theorem piIsoPi_inv_π {ι : Type v} (α : ι → TopCatMax.{v, u}) (i : ι) :
    (piIsoPi α).inv ≫ Pi.π α i = piπ α i := by 

Proof state:
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
i : ι
⊢ (piIsoPi α).inv ≫ Pi.π α i = piπ α i

Next tactic:
simp [piIsoPi]
@[simp]
theorem piIsoPi_hom_apply {ι : Type v} (α : ι → TopCatMax.{v, u}) (i : ι)
    (x : (∏ α : TopCatMax.{v, u})) : (piIsoPi α).hom x i = (Pi.π α i : _) x := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
i : ι
x : ↑(∏ α)
⊢ (piIsoPi α).hom x i = (Pi.π α i) x

Next tactic:
have := piIsoPi_inv_π α i
@[simp]
theorem piIsoPi_hom_apply {ι : Type v} (α : ι → TopCatMax.{v, u}) (i : ι)
    (x : (∏ α : TopCatMax.{v, u})) : (piIsoPi α).hom x i = (Pi.π α i : _) x := by
  have := piIsoPi_inv_π α i
  

Proof state:
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
i : ι
x : ↑(∏ α)
this : (piIsoPi α).inv ≫ Pi.π α i = piπ α i
⊢ (piIsoPi α).hom x i = (Pi.π α i) x

Next tactic:
rw [Iso.inv_comp_eq] at this
@[simp]
theorem piIsoPi_hom_apply {ι : Type v} (α : ι → TopCatMax.{v, u}) (i : ι)
    (x : (∏ α : TopCatMax.{v, u})) : (piIsoPi α).hom x i = (Pi.π α i : _) x := by
  have := piIsoPi_inv_π α i
  rw [Iso.inv_comp_eq] at this
  

Proof state:
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
i : ι
x : ↑(∏ α)
this : Pi.π α i = (piIsoPi α).hom ≫ piπ α i
⊢ (piIsoPi α).hom x i = (Pi.π α i) x

Next tactic:
exact ConcreteCategory.congr_hom this x
/-- The inclusion to the coproduct as a bundled continuous map. -/
abbrev sigmaι {ι : Type v} (α : ι → TopCatMax.{v,u}) (i : ι) : α i ⟶ TopCat.of (Σi, α i) := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
i : ι
⊢ α i ⟶ of ((i : ι) × ↑(α i))

Next tactic:
refine ContinuousMap.mk ?_ ?_
/-- The inclusion to the coproduct as a bundled continuous map. -/
abbrev sigmaι {ι : Type v} (α : ι → TopCatMax.{v,u}) (i : ι) : α i ⟶ TopCat.of (Σi, α i) := by
  refine ContinuousMap.mk ?_ ?_
  · 

Proof state:
case refine_1
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
i : ι
⊢ ↑(α i) → ↑(of ((i : ι) × ↑(α i)))

Next tactic:
dsimp
/-- The inclusion to the coproduct as a bundled continuous map. -/
abbrev sigmaι {ι : Type v} (α : ι → TopCatMax.{v,u}) (i : ι) : α i ⟶ TopCat.of (Σi, α i) := by
  refine ContinuousMap.mk ?_ ?_
  · dsimp
    

Proof state:
case refine_1
J : Type v
inst✝ : SmallCategory J
ι : Type v
α : ι → TopCatMax
i : ι
⊢ ↑(α i) → (i : ι) × ↑(α i)

Next tactic:
apply Sigma.mk i