l3lab/ntp-mathlib huggingface dataset:
/-- The unit object is always closed.
This isn't an instance because most of the time we'll prove closedness for all objects at once,
rather than just for this one.
-/
def unitClosed : Closed (𝟙_ C) where
  isAdj :=
    { right := 𝟭 C
      adj :=
        Adjunction.mkOfHomEquiv
          { homEquiv := fun X _ =>
              { toFun := fun a => (leftUnitor X).inv ≫ a
                invFun := fun a => (leftUnitor X).hom ≫ a
                left_inv := by aesop_cat
                right_inv := by aesop_cat }
            homEquiv_naturality_left_symm := fun f g => by
              

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
X'✝ X✝ Y✝ : C
f : X'✝ ⟶ X✝
g : X✝ ⟶ (𝟭 C).obj Y✝
⊢ ((fun X x =>
            { toFun := fun a => (λ_ X).inv ≫ a, invFun := fun a => (λ_ X).hom ≫ a,
              left_inv := (_ : ∀ (x_1 : (tensorLeft (𝟙_ C)).obj X ⟶ x), (λ_ X).hom ≫ (λ_ X).inv ≫ x_1 = x_1),
              right_inv := (_ : ∀ (x_1 : X ⟶ (𝟭 C).obj x), (λ_ X).inv ≫ (λ_ X).hom ≫ x_1 = x_1) })
          X'✝ Y✝).symm
      (f ≫ g) =
    (tensorLeft (𝟙_ C)).map f ≫
      ((fun X x =>
              { toFun := fun a => (λ_ X).inv ≫ a, invFun := fun a => (λ_ X).hom ≫ a,
                left_inv := (_ : ∀ (x_1 : (tensorLeft (𝟙_ C)).obj X ⟶ x), (λ_ X).hom ≫ (λ_ X).inv ≫ x_1 = x_1),
                right_inv := (_ : ∀ (x_1 : X ⟶ (𝟭 C).obj x), (λ_ X).inv ≫ (λ_ X).hom ≫ x_1 = x_1) })
            X✝ Y✝).symm
        g

Next tactic:
dsimp
/-- The unit object is always closed.
This isn't an instance because most of the time we'll prove closedness for all objects at once,
rather than just for this one.
-/
def unitClosed : Closed (𝟙_ C) where
  isAdj :=
    { right := 𝟭 C
      adj :=
        Adjunction.mkOfHomEquiv
          { homEquiv := fun X _ =>
              { toFun := fun a => (leftUnitor X).inv ≫ a
                invFun := fun a => (leftUnitor X).hom ≫ a
                left_inv := by aesop_cat
                right_inv := by aesop_cat }
            homEquiv_naturality_left_symm := fun f g => by
              dsimp
              

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
X'✝ X✝ Y✝ : C
f : X'✝ ⟶ X✝
g : X✝ ⟶ (𝟭 C).obj Y✝
⊢ (λ_ X'✝).hom ≫ f ≫ g = (𝟙 (𝟙_ C) ⊗ f) ≫ (λ_ X✝).hom ≫ g

Next tactic:
rw [leftUnitor_naturality_assoc]
/-- The unit object is always closed.
This isn't an instance because most of the time we'll prove closedness for all objects at once,
rather than just for this one.
-/
def unitClosed : Closed (𝟙_ C) where
  isAdj :=
    { right := 𝟭 C
      adj :=
        Adjunction.mkOfHomEquiv
          { homEquiv := fun X _ =>
              { toFun := fun a => (leftUnitor X).inv ≫ a
                invFun := fun a => (leftUnitor X).hom ≫ a
                left_inv := by aesop_cat
                right_inv := by aesop_cat }
            homEquiv_naturality_left_symm := fun f g => by
              dsimp
              rw [leftUnitor_naturality_assoc]
            -- This used to be automatic before leanprover/lean4#2644
            homEquiv_naturality_right := by  -- aesop failure
              

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
⊢ ∀ {X Y Y' : C} (f : (tensorLeft (𝟙_ C)).obj X ⟶ Y) (g : Y ⟶ Y'),
    ((fun X x =>
            { toFun := fun a => (λ_ X).inv ≫ a, invFun := fun a => (λ_ X).hom ≫ a,
              left_inv := (_ : ∀ (x_1 : (tensorLeft (𝟙_ C)).obj X ⟶ x), (λ_ X).hom ≫ (λ_ X).inv ≫ x_1 = x_1),
              right_inv := (_ : ∀ (x_1 : X ⟶ (𝟭 C).obj x), (λ_ X).inv ≫ (λ_ X).hom ≫ x_1 = x_1) })
          X Y')
        (f ≫ g) =
      ((fun X x =>
              { toFun := fun a => (λ_ X).inv ≫ a, invFun := fun a => (λ_ X).hom ≫ a,
                left_inv := (_ : ∀ (x_1 : (tensorLeft (𝟙_ C)).obj X ⟶ x), (λ_ X).hom ≫ (λ_ X).inv ≫ x_1 = x_1),
                right_inv := (_ : ∀ (x_1 : X ⟶ (𝟭 C).obj x), (λ_ X).inv ≫ (λ_ X).hom ≫ x_1 = x_1) })
            X Y)
          f ≫
        (𝟭 C).map g

Next tactic:
dsimp
/-- The unit object is always closed.
This isn't an instance because most of the time we'll prove closedness for all objects at once,
rather than just for this one.
-/
def unitClosed : Closed (𝟙_ C) where
  isAdj :=
    { right := 𝟭 C
      adj :=
        Adjunction.mkOfHomEquiv
          { homEquiv := fun X _ =>
              { toFun := fun a => (leftUnitor X).inv ≫ a
                invFun := fun a => (leftUnitor X).hom ≫ a
                left_inv := by aesop_cat
                right_inv := by aesop_cat }
            homEquiv_naturality_left_symm := fun f g => by
              dsimp
              rw [leftUnitor_naturality_assoc]
            -- This used to be automatic before leanprover/lean4#2644
            homEquiv_naturality_right := by  -- aesop failure
              dsimp
              

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
⊢ ∀ {X Y Y' : C} (f : 𝟙_ C ⊗ X ⟶ Y) (g : Y ⟶ Y'), (λ_ X).inv ≫ f ≫ g = ((λ_ X).inv ≫ f) ≫ g

Next tactic:
simp
theorem uncurry_id_eq_ev : uncurry (𝟙 (A ⟶[C] X)) = (ihom.ev A).app X := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : MonoidalCategory C
A B X X' Y Y' Z : C
inst✝ : Closed A
⊢ uncurry (𝟙 ((ihom A).obj X)) = (ihom.ev A).app X

Next tactic:
rw [uncurry_eq, tensor_id, id_comp]
theorem curry_id_eq_coev : curry (𝟙 _) = (ihom.coev A).app X := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : MonoidalCategory C
A B X X' Y Y' Z : C
inst✝ : Closed A
⊢ curry (𝟙 (A ⊗ (𝟭 C).obj X)) = (ihom.coev A).app X

Next tactic:
rw [curry_eq, (ihom A).map_id (A ⊗ _)]
theorem curry_id_eq_coev : curry (𝟙 _) = (ihom.coev A).app X := by
  rw [curry_eq, (ihom A).map_id (A ⊗ _)]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : MonoidalCategory C
A B X X' Y Y' Z : C
inst✝ : Closed A
⊢ (ihom.coev A).app ((𝟭 C).obj X) ≫ 𝟙 ((ihom A).obj (A ⊗ (𝟭 C).obj X)) = (ihom.coev A).app X

Next tactic:
apply comp_id
@[simp]
theorem uncurry_pre (f : B ⟶ A) (X : C) :
    MonoidalClosed.uncurry ((pre f).app X) = (f ⊗ 𝟙 _) ≫ (ihom.ev A).app X := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : MonoidalCategory C
A B X✝ X' Y Y' Z : C
inst✝¹ : Closed A
inst✝ : Closed B
f : B ⟶ A
X : C
⊢ uncurry ((pre f).app X) = (f ⊗ 𝟙 ((ihom A).obj X)) ≫ (ihom.ev A).app X

Next tactic:
rw [uncurry_eq, id_tensor_pre_app_comp_ev]
@[simp]
theorem pre_id (A : C) [Closed A] : pre (𝟙 A) = 𝟙 _ := by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : MonoidalCategory C
A✝ B X X' Y Y' Z : C
inst✝² : Closed A✝
inst✝¹ : Closed B
A : C
inst✝ : Closed A
⊢ pre (𝟙 A) = 𝟙 (ihom A)

Next tactic:
simp only [pre, Functor.map_id]
@[simp]
theorem pre_id (A : C) [Closed A] : pre (𝟙 A) = 𝟙 _ := by
  simp only [pre, Functor.map_id]
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : MonoidalCategory C
A✝ B X X' Y Y' Z : C
inst✝² : Closed A✝
inst✝¹ : Closed B
A : C
inst✝ : Closed A
⊢ (transferNatTransSelf (ihom.adjunction A) (ihom.adjunction A)) (𝟙 ((tensoringLeft C).obj A)) = 𝟙 (ihom A)

Next tactic:
dsimp
@[simp]
theorem pre_id (A : C) [Closed A] : pre (𝟙 A) = 𝟙 _ := by
  simp only [pre, Functor.map_id]
  dsimp
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : MonoidalCategory C
A✝ B X X' Y Y' Z : C
inst✝² : Closed A✝
inst✝¹ : Closed B
A : C
inst✝ : Closed A
⊢ (transferNatTransSelf (ihom.adjunction A) (ihom.adjunction A)) (𝟙 (tensorLeft A)) = 𝟙 (ihom A)

Next tactic:
simp
@[simp]
theorem pre_map {A₁ A₂ A₃ : C} [Closed A₁] [Closed A₂] [Closed A₃] (f : A₁ ⟶ A₂) (g : A₂ ⟶ A₃) :
    pre (f ≫ g) = pre g ≫ pre f := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : MonoidalCategory C
A B X X' Y Y' Z : C
inst✝⁴ : Closed A
inst✝³ : Closed B
A₁ A₂ A₃ : C
inst✝² : Closed A₁
inst✝¹ : Closed A₂
inst✝ : Closed A₃
f : A₁ ⟶ A₂
g : A₂ ⟶ A₃
⊢ pre (f ≫ g) = pre g ≫ pre f

Next tactic:
rw [pre, pre, pre, transferNatTransSelf_comp, (tensoringLeft C).map_comp]
theorem pre_comm_ihom_map {W X Y Z : C} [Closed W] [Closed X] (f : W ⟶ X) (g : Y ⟶ Z) :
    (pre f).app Y ≫ (ihom W).map g = (ihom X).map g ≫ (pre f).app Z := by 

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : MonoidalCategory C
A B X✝ X' Y✝ Y' Z✝ : C
inst✝³ : Closed A
inst✝² : Closed B
W X Y Z : C
inst✝¹ : Closed W
inst✝ : Closed X
f : W ⟶ X
g : Y ⟶ Z
⊢ (pre f).app Y ≫ (ihom W).map g = (ihom X).map g ≫ (pre f).app Z

Next tactic:
simp
/-- Transport the property of being monoidal closed across a monoidal equivalence of categories -/
noncomputable def ofEquiv (F : MonoidalFunctor C D) [IsEquivalence F.toFunctor]
    [h : MonoidalClosed D] : MonoidalClosed C where
  closed X :=
    { isAdj := by
        

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : MonoidalCategory C
A B X✝ X' Y Y' Z : C
inst✝³ : Closed A
D : Type u₂
inst✝² : Category.{v₂, u₂} D
inst✝¹ : MonoidalCategory D
F : MonoidalFunctor C D
inst✝ : IsEquivalence F.toFunctor
h : MonoidalClosed D
X : C
⊢ IsLeftAdjoint (tensorLeft X)

Next tactic:
haveI q : Closed (F.obj X) := inferInstance
/-- Transport the property of being monoidal closed across a monoidal equivalence of categories -/
noncomputable def ofEquiv (F : MonoidalFunctor C D) [IsEquivalence F.toFunctor]
    [h : MonoidalClosed D] : MonoidalClosed C where
  closed X :=
    { isAdj := by
        haveI q : Closed (F.obj X) := inferInstance
        

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : MonoidalCategory C
A B X✝ X' Y Y' Z : C
inst✝³ : Closed A
D : Type u₂
inst✝² : Category.{v₂, u₂} D
inst✝¹ : MonoidalCategory D
F : MonoidalFunctor C D
inst✝ : IsEquivalence F.toFunctor
h : MonoidalClosed D
X : C
q : Closed (F.obj X)
⊢ IsLeftAdjoint (tensorLeft X)

Next tactic:
haveI : IsLeftAdjoint (tensorLeft (F.obj X)) := q.isAdj
/-- Transport the property of being monoidal closed across a monoidal equivalence of categories -/
noncomputable def ofEquiv (F : MonoidalFunctor C D) [IsEquivalence F.toFunctor]
    [h : MonoidalClosed D] : MonoidalClosed C where
  closed X :=
    { isAdj := by
        haveI q : Closed (F.obj X) := inferInstance
        haveI : IsLeftAdjoint (tensorLeft (F.obj X)) := q.isAdj
        

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : MonoidalCategory C
A B X✝ X' Y Y' Z : C
inst✝³ : Closed A
D : Type u₂
inst✝² : Category.{v₂, u₂} D
inst✝¹ : MonoidalCategory D
F : MonoidalFunctor C D
inst✝ : IsEquivalence F.toFunctor
h : MonoidalClosed D
X : C
q : Closed (F.obj X)
this : IsLeftAdjoint (tensorLeft (F.obj X))
⊢ IsLeftAdjoint (tensorLeft X)

Next tactic:
have i := compInvIso (MonoidalFunctor.commTensorLeft F X)
/-- Transport the property of being monoidal closed across a monoidal equivalence of categories -/
noncomputable def ofEquiv (F : MonoidalFunctor C D) [IsEquivalence F.toFunctor]
    [h : MonoidalClosed D] : MonoidalClosed C where
  closed X :=
    { isAdj := by
        haveI q : Closed (F.obj X) := inferInstance
        haveI : IsLeftAdjoint (tensorLeft (F.obj X)) := q.isAdj
        have i := compInvIso (MonoidalFunctor.commTensorLeft F X)
        

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : MonoidalCategory C
A B X✝ X' Y Y' Z : C
inst✝³ : Closed A
D : Type u₂
inst✝² : Category.{v₂, u₂} D
inst✝¹ : MonoidalCategory D
F : MonoidalFunctor C D
inst✝ : IsEquivalence F.toFunctor
h : MonoidalClosed D
X : C
q : Closed (F.obj X)
this : IsLeftAdjoint (tensorLeft (F.obj X))
i : (F.toFunctor ⋙ tensorLeft (F.obj X)) ⋙ Functor.inv F.toFunctor ≅ tensorLeft X
⊢ IsLeftAdjoint (tensorLeft X)

Next tactic:
exact Adjunction.leftAdjointOfNatIso i
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  

Proof state:
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
⊢ radius p = liminf (fun n => 1 / ↑(‖p n‖₊ ^ (1 / ↑n))) atTop

Next tactic:
have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
    conv_lhs =>
      rw [one_div, ENNReal.le_inv_iff_mul_le, ← ENNReal.coe_mul, ENNReal.coe_le_one_iff, one_div, ←
        NNReal.rpow_one r, ← mul_inv_cancel this.ne', NNReal.rpow_mul, ← NNReal.mul_rpow, ←
        NNReal.one_rpow n⁻¹, NNReal.rpow_le_rpow_iff (inv_pos.2 this), mul_comm,
        NNReal.rpow_nat_cast]
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    

Proof state:
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
⊢ ∀ (r : ℝ≥0) {n : ℕ}, 0 < n → (↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n)) ↔ ‖p n‖₊ * r ^ n ≤ 1)

Next tactic:
intro r n hn
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    

Proof state:
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
r : ℝ≥0
n : ℕ
hn : 0 < n
⊢ ↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n)) ↔ ‖p n‖₊ * r ^ n ≤ 1

Next tactic:
have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
    

Proof state:
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
r : ℝ≥0
n : ℕ
hn : 0 < n
this : 0 < ↑n
⊢ ↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n)) ↔ ‖p n‖₊ * r ^ n ≤ 1

Next tactic:
conv_lhs =>
      rw [one_div, ENNReal.le_inv_iff_mul_le, ← ENNReal.coe_mul, ENNReal.coe_le_one_iff, one_div, ←
        NNReal.rpow_one r, ← mul_inv_cancel this.ne', NNReal.rpow_mul, ← NNReal.mul_rpow, ←
        NNReal.one_rpow n⁻¹, NNReal.rpow_le_rpow_iff (inv_pos.2 this), mul_comm,
        NNReal.rpow_nat_cast]
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
    conv_lhs =>
      

Proof state:
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
r : ℝ≥0
n : ℕ
hn : 0 < n
this : 0 < ↑n
| ↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n))

Next tactic:
rw [one_div, ENNReal.le_inv_iff_mul_le, ← ENNReal.coe_mul, ENNReal.coe_le_one_iff, one_div, ←
        NNReal.rpow_one r, ← mul_inv_cancel this.ne', NNReal.rpow_mul, ← NNReal.mul_rpow, ←
        NNReal.one_rpow n⁻¹, NNReal.rpow_le_rpow_iff (inv_pos.2 this), mul_comm,
        NNReal.rpow_nat_cast]
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
    conv_lhs =>
      rw [one_div, ENNReal.le_inv_iff_mul_le, ← ENNReal.coe_mul, ENNReal.coe_le_one_iff, one_div, ←
        NNReal.rpow_one r, ← mul_inv_cancel this.ne', NNReal.rpow_mul, ← NNReal.mul_rpow, ←
        NNReal.one_rpow n⁻¹, NNReal.rpow_le_rpow_iff (inv_pos.2 this), mul_comm,
        NNReal.rpow_nat_cast]
  

Proof state:
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
this : ∀ (r : ℝ≥0) {n : ℕ}, 0 < n → (↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n)) ↔ ‖p n‖₊ * r ^ n ≤ 1)
⊢ radius p = liminf (fun n => 1 / ↑(‖p n‖₊ ^ (1 / ↑n))) atTop

Next tactic:
apply le_antisymm
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
    conv_lhs =>
      rw [one_div, ENNReal.le_inv_iff_mul_le, ← ENNReal.coe_mul, ENNReal.coe_le_one_iff, one_div, ←
        NNReal.rpow_one r, ← mul_inv_cancel this.ne', NNReal.rpow_mul, ← NNReal.mul_rpow, ←
        NNReal.one_rpow n⁻¹, NNReal.rpow_le_rpow_iff (inv_pos.2 this), mul_comm,
        NNReal.rpow_nat_cast]
  apply le_antisymm <;> 

Proof state:
case a
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
this : ∀ (r : ℝ≥0) {n : ℕ}, 0 < n → (↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n)) ↔ ‖p n‖₊ * r ^ n ≤ 1)
⊢ radius p ≤ liminf (fun n => 1 / ↑(‖p n‖₊ ^ (1 / ↑n))) atTop

Next tactic:
refine' ENNReal.le_of_forall_nnreal_lt fun r hr => _
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
    conv_lhs =>
      rw [one_div, ENNReal.le_inv_iff_mul_le, ← ENNReal.coe_mul, ENNReal.coe_le_one_iff, one_div, ←
        NNReal.rpow_one r, ← mul_inv_cancel this.ne', NNReal.rpow_mul, ← NNReal.mul_rpow, ←
        NNReal.one_rpow n⁻¹, NNReal.rpow_le_rpow_iff (inv_pos.2 this), mul_comm,
        NNReal.rpow_nat_cast]
  apply le_antisymm <;> 

Proof state:
case a
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
this : ∀ (r : ℝ≥0) {n : ℕ}, 0 < n → (↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n)) ↔ ‖p n‖₊ * r ^ n ≤ 1)
⊢ liminf (fun n => 1 / ↑(‖p n‖₊ ^ (1 / ↑n))) atTop ≤ radius p

Next tactic:
refine' ENNReal.le_of_forall_nnreal_lt fun r hr => _
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
    conv_lhs =>
      rw [one_div, ENNReal.le_inv_iff_mul_le, ← ENNReal.coe_mul, ENNReal.coe_le_one_iff, one_div, ←
        NNReal.rpow_one r, ← mul_inv_cancel this.ne', NNReal.rpow_mul, ← NNReal.mul_rpow, ←
        NNReal.one_rpow n⁻¹, NNReal.rpow_le_rpow_iff (inv_pos.2 this), mul_comm,
        NNReal.rpow_nat_cast]
  apply le_antisymm <;> refine' ENNReal.le_of_forall_nnreal_lt fun r hr => _
  · 

Proof state:
case a
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
this : ∀ (r : ℝ≥0) {n : ℕ}, 0 < n → (↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n)) ↔ ‖p n‖₊ * r ^ n ≤ 1)
r : ℝ≥0
hr : ↑r < radius p
⊢ ↑r ≤ liminf (fun n => 1 / ↑(‖p n‖₊ ^ (1 / ↑n))) atTop

Next tactic:
have := ((TFAE_exists_lt_isLittleO_pow (fun n => ‖p n‖ * r ^ n) 1).out 1 7).1
      (p.isLittleO_of_lt_radius hr)
/-- The radius of a formal multilinear series is equal to
$\liminf_{n\to\infty} \frac{1}{\sqrt[n]{‖p n‖}}$. The actual statement uses `ℝ≥0` and some
coercions. -/
theorem radius_eq_liminf :
    p.radius = liminf (fun n => (1 / (‖p n‖₊ ^ (1 / (n : ℝ)) : ℝ≥0) : ℝ≥0∞)) atTop := by
  -- porting note: added type ascription to make elaborated statement match Lean 3 version
  have :
    ∀ (r : ℝ≥0) {n : ℕ},
      0 < n → ((r : ℝ≥0∞) ≤ 1 / ↑(‖p n‖₊ ^ (1 / (n : ℝ))) ↔ ‖p n‖₊ * r ^ n ≤ 1) := by
    intro r n hn
    have : 0 < (n : ℝ) := Nat.cast_pos.2 hn
    conv_lhs =>
      rw [one_div, ENNReal.le_inv_iff_mul_le, ← ENNReal.coe_mul, ENNReal.coe_le_one_iff, one_div, ←
        NNReal.rpow_one r, ← mul_inv_cancel this.ne', NNReal.rpow_mul, ← NNReal.mul_rpow, ←
        NNReal.one_rpow n⁻¹, NNReal.rpow_le_rpow_iff (inv_pos.2 this), mul_comm,
        NNReal.rpow_nat_cast]
  apply le_antisymm <;> refine' ENNReal.le_of_forall_nnreal_lt fun r hr => _
  · have := ((TFAE_exists_lt_isLittleO_pow (fun n => ‖p n‖ * r ^ n) 1).out 1 7).1
      (p.isLittleO_of_lt_radius hr)
    

Proof state:
case a
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
p : FormalMultilinearSeries 𝕜 E F
this✝ : ∀ (r : ℝ≥0) {n : ℕ}, 0 < n → (↑r ≤ 1 / ↑(‖p n‖₊ ^ (1 / ↑n)) ↔ ‖p n‖₊ * r ^ n ≤ 1)
r : ℝ≥0
hr : ↑r < radius p
this : ∃ a ∈ Set.Ioo 0 1, ∀ᶠ (n : ℕ) in atTop, |‖p n‖ * ↑r ^ n| ≤ a ^ n
⊢ ↑r ≤ liminf (fun n => 1 / ↑(‖p n‖₊ ^ (1 / ↑n))) atTop

Next tactic:
obtain ⟨a, ha, H⟩ := this