l3lab/ntp-mathlib huggingface dataset:
/--
If `X` is homotopy equivalent to `Y`, and `Y` is homotopy equivalent to `Z`, then `X` is homotopy
equivalent to `Z`.
-/
@[simps!]
def trans (h₁ : X ≃ₕ Y) (h₂ : Y ≃ₕ Z) : X ≃ₕ Z where
  toFun := h₂.toFun.comp h₁.toFun
  invFun := h₁.invFun.comp h₂.invFun
  left_inv := by
    refine Homotopic.trans ?_ h₁.left_inv
    

Proof state:
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h₁ : X ≃ₕ Y
h₂ : Y ≃ₕ Z
⊢ Homotopic (comp (comp h₁.invFun h₂.invFun) (comp h₂.toFun h₁.toFun)) (comp h₁.invFun h₁.toFun)

Next tactic:
exact ((Homotopic.refl _).hcomp h₂.left_inv).hcomp (Homotopic.refl _)
/--
If `X` is homotopy equivalent to `Y`, and `Y` is homotopy equivalent to `Z`, then `X` is homotopy
equivalent to `Z`.
-/
@[simps!]
def trans (h₁ : X ≃ₕ Y) (h₂ : Y ≃ₕ Z) : X ≃ₕ Z where
  toFun := h₂.toFun.comp h₁.toFun
  invFun := h₁.invFun.comp h₂.invFun
  left_inv := by
    refine Homotopic.trans ?_ h₁.left_inv
    exact ((Homotopic.refl _).hcomp h₂.left_inv).hcomp (Homotopic.refl _)
  right_inv := by
    

Proof state:
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h₁ : X ≃ₕ Y
h₂ : Y ≃ₕ Z
⊢ Homotopic (comp (comp h₂.toFun h₁.toFun) (comp h₁.invFun h₂.invFun)) (ContinuousMap.id Z)

Next tactic:
refine Homotopic.trans ?_ h₂.right_inv
/--
If `X` is homotopy equivalent to `Y`, and `Y` is homotopy equivalent to `Z`, then `X` is homotopy
equivalent to `Z`.
-/
@[simps!]
def trans (h₁ : X ≃ₕ Y) (h₂ : Y ≃ₕ Z) : X ≃ₕ Z where
  toFun := h₂.toFun.comp h₁.toFun
  invFun := h₁.invFun.comp h₂.invFun
  left_inv := by
    refine Homotopic.trans ?_ h₁.left_inv
    exact ((Homotopic.refl _).hcomp h₂.left_inv).hcomp (Homotopic.refl _)
  right_inv := by
    refine Homotopic.trans ?_ h₂.right_inv
    

Proof state:
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
h₁ : X ≃ₕ Y
h₂ : Y ≃ₕ Z
⊢ Homotopic (comp (comp h₂.toFun h₁.toFun) (comp h₁.invFun h₂.invFun)) (comp h₂.toFun h₂.invFun)

Next tactic:
exact ((Homotopic.refl _).hcomp h₁.right_inv).hcomp (Homotopic.refl _)
theorem lieCharacter_apply_lie (χ : LieCharacter R L) (x y : L) : χ ⁅x, y⁆ = 0 := by
  

Proof state:
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x y : L
⊢ χ ⁅x, y⁆ = 0

Next tactic:
rw [LieHom.map_lie, LieRing.of_associative_ring_bracket, mul_comm, sub_self]
@[simp]
theorem lieCharacter_apply_lie' (χ : LieCharacter R L) (x y : L) : ⁅χ x, χ y⁆ = 0 := by
  

Proof state:
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x y : L
⊢ ⁅χ x, χ y⁆ = 0

Next tactic:
rw [LieRing.of_associative_ring_bracket, mul_comm, sub_self]
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  

Proof state:
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ derivedSeries R L 1
⊢ χ x = 0

Next tactic:
rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
  

Proof state:
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ Submodule.span R {m | ∃ x n, ⁅↑x, ↑n⁆ = m}
⊢ χ x = 0

Next tactic:
refine' Submodule.span_induction h _ _ _ _
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
  refine' Submodule.span_induction h _ _ _ _
  · 

Proof state:
case refine'_1
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ Submodule.span R {m | ∃ x n, ⁅↑x, ↑n⁆ = m}
⊢ ∀ x ∈ {m | ∃ x n, ⁅↑x, ↑n⁆ = m}, χ x = 0

Next tactic:
rintro y ⟨⟨z, hz⟩, ⟨⟨w, hw⟩, rfl⟩⟩
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
  refine' Submodule.span_induction h _ _ _ _
  · rintro y ⟨⟨z, hz⟩, ⟨⟨w, hw⟩, rfl⟩⟩; 

Proof state:
case refine'_1.intro.mk.intro.mk
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ Submodule.span R {m | ∃ x n, ⁅↑x, ↑n⁆ = m}
z : L
hz : z ∈ ⊤
w : L
hw : w ∈ ⊤
⊢ χ ⁅↑{ val := z, property := hz }, ↑{ val := w, property := hw }⁆ = 0

Next tactic:
apply lieCharacter_apply_lie
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
  refine' Submodule.span_induction h _ _ _ _
  · rintro y ⟨⟨z, hz⟩, ⟨⟨w, hw⟩, rfl⟩⟩; apply lieCharacter_apply_lie
  · 

Proof state:
case refine'_2
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ Submodule.span R {m | ∃ x n, ⁅↑x, ↑n⁆ = m}
⊢ χ 0 = 0

Next tactic:
exact χ.map_zero
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
  refine' Submodule.span_induction h _ _ _ _
  · rintro y ⟨⟨z, hz⟩, ⟨⟨w, hw⟩, rfl⟩⟩; apply lieCharacter_apply_lie
  · exact χ.map_zero
  · 

Proof state:
case refine'_3
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ Submodule.span R {m | ∃ x n, ⁅↑x, ↑n⁆ = m}
⊢ ∀ (x y : L), χ x = 0 → χ y = 0 → χ (x + y) = 0

Next tactic:
intro y z hy hz
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
  refine' Submodule.span_induction h _ _ _ _
  · rintro y ⟨⟨z, hz⟩, ⟨⟨w, hw⟩, rfl⟩⟩; apply lieCharacter_apply_lie
  · exact χ.map_zero
  · intro y z hy hz; 

Proof state:
case refine'_3
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ Submodule.span R {m | ∃ x n, ⁅↑x, ↑n⁆ = m}
y z : L
hy : χ y = 0
hz : χ z = 0
⊢ χ (y + z) = 0

Next tactic:
rw [LieHom.map_add, hy, hz, add_zero]
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
  refine' Submodule.span_induction h _ _ _ _
  · rintro y ⟨⟨z, hz⟩, ⟨⟨w, hw⟩, rfl⟩⟩; apply lieCharacter_apply_lie
  · exact χ.map_zero
  · intro y z hy hz; rw [LieHom.map_add, hy, hz, add_zero]
  · 

Proof state:
case refine'_4
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ Submodule.span R {m | ∃ x n, ⁅↑x, ↑n⁆ = m}
⊢ ∀ (a : R) (x : L), χ x = 0 → χ (a • x) = 0

Next tactic:
intro t y hy
theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L}
    (h : x ∈ derivedSeries R L 1) : χ x = 0 := by
  rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ←
    LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h
  refine' Submodule.span_induction h _ _ _ _
  · rintro y ⟨⟨z, hz⟩, ⟨⟨w, hw⟩, rfl⟩⟩; apply lieCharacter_apply_lie
  · exact χ.map_zero
  · intro y z hy hz; rw [LieHom.map_add, hy, hz, add_zero]
  · intro t y hy; 

Proof state:
case refine'_4
R : Type u
L : Type v
inst✝² : CommRing R
inst✝¹ : LieRing L
inst✝ : LieAlgebra R L
χ : LieCharacter R L
x : L
h : x ∈ Submodule.span R {m | ∃ x n, ⁅↑x, ↑n⁆ = m}
t : R
y : L
hy : χ y = 0
⊢ χ (t • y) = 0

Next tactic:
rw [LieHom.map_smul, hy, smul_zero]
/-- For an Abelian Lie algebra, characters are just linear forms. -/
@[simps! apply symm_apply]
def lieCharacterEquivLinearDual [IsLieAbelian L] : LieCharacter R L ≃ Module.Dual R L where
  toFun χ := (χ : L →ₗ[R] R)
  invFun ψ :=
    { ψ with
      map_lie' := fun {x y} => by
        

Proof state:
R : Type u
L : Type v
inst✝³ : CommRing R
inst✝² : LieRing L
inst✝¹ : LieAlgebra R L
inst✝ : IsLieAbelian L
ψ : Module.Dual R L
x y : L
⊢ AddHom.toFun
      { toAddHom := ψ.toAddHom,
          map_smul' :=
            (_ :
              ∀ (r : R) (x : L),
                AddHom.toFun ψ.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
      ⁅x, y⁆ =
    ⁅AddHom.toFun
        { toAddHom := ψ.toAddHom,
            map_smul' :=
              (_ :
                ∀ (r : R) (x : L),
                  AddHom.toFun ψ.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
        x,
      AddHom.toFun
        { toAddHom := ψ.toAddHom,
            map_smul' :=
              (_ :
                ∀ (r : R) (x : L),
                  AddHom.toFun ψ.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
        y⁆

Next tactic:
rw [LieModule.IsTrivial.trivial, LieRing.of_associative_ring_bracket, mul_comm, sub_self,
          LinearMap.toFun_eq_coe, LinearMap.map_zero]
/-- For an Abelian Lie algebra, characters are just linear forms. -/
@[simps! apply symm_apply]
def lieCharacterEquivLinearDual [IsLieAbelian L] : LieCharacter R L ≃ Module.Dual R L where
  toFun χ := (χ : L →ₗ[R] R)
  invFun ψ :=
    { ψ with
      map_lie' := fun {x y} => by
        rw [LieModule.IsTrivial.trivial, LieRing.of_associative_ring_bracket, mul_comm, sub_self,
          LinearMap.toFun_eq_coe, LinearMap.map_zero] }
  left_inv χ := by 

Proof state:
R : Type u
L : Type v
inst✝³ : CommRing R
inst✝² : LieRing L
inst✝¹ : LieAlgebra R L
inst✝ : IsLieAbelian L
χ : LieCharacter R L
⊢ (fun ψ =>
        {
          toLinearMap :=
            { toAddHom := ψ.toAddHom,
              map_smul' :=
                (_ :
                  ∀ (r : R) (x : L), AddHom.toFun ψ.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) },
          map_lie' :=
            (_ :
              ∀ {x y : L},
                AddHom.toFun
                    { toAddHom := ψ.toAddHom,
                        map_smul' :=
                          (_ :
                            ∀ (r : R) (x : L),
                              AddHom.toFun ψ.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                    ⁅x, y⁆ =
                  ⁅AddHom.toFun
                      { toAddHom := ψ.toAddHom,
                          map_smul' :=
                            (_ :
                              ∀ (r : R) (x : L),
                                AddHom.toFun ψ.toAddHom (r • x) =
                                  (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                      x,
                    AddHom.toFun
                      { toAddHom := ψ.toAddHom,
                          map_smul' :=
                            (_ :
                              ∀ (r : R) (x : L),
                                AddHom.toFun ψ.toAddHom (r • x) =
                                  (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                      y⁆) })
      ((fun χ => ↑χ) χ) =
    χ

Next tactic:
ext
/-- For an Abelian Lie algebra, characters are just linear forms. -/
@[simps! apply symm_apply]
def lieCharacterEquivLinearDual [IsLieAbelian L] : LieCharacter R L ≃ Module.Dual R L where
  toFun χ := (χ : L →ₗ[R] R)
  invFun ψ :=
    { ψ with
      map_lie' := fun {x y} => by
        rw [LieModule.IsTrivial.trivial, LieRing.of_associative_ring_bracket, mul_comm, sub_self,
          LinearMap.toFun_eq_coe, LinearMap.map_zero] }
  left_inv χ := by ext; 

Proof state:
case h
R : Type u
L : Type v
inst✝³ : CommRing R
inst✝² : LieRing L
inst✝¹ : LieAlgebra R L
inst✝ : IsLieAbelian L
χ : LieCharacter R L
x✝ : L
⊢ ((fun ψ =>
          {
            toLinearMap :=
              { toAddHom := ψ.toAddHom,
                map_smul' :=
                  (_ :
                    ∀ (r : R) (x : L),
                      AddHom.toFun ψ.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) },
            map_lie' :=
              (_ :
                ∀ {x y : L},
                  AddHom.toFun
                      { toAddHom := ψ.toAddHom,
                          map_smul' :=
                            (_ :
                              ∀ (r : R) (x : L),
                                AddHom.toFun ψ.toAddHom (r • x) =
                                  (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                      ⁅x, y⁆ =
                    ⁅AddHom.toFun
                        { toAddHom := ψ.toAddHom,
                            map_smul' :=
                              (_ :
                                ∀ (r : R) (x : L),
                                  AddHom.toFun ψ.toAddHom (r • x) =
                                    (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                        x,
                      AddHom.toFun
                        { toAddHom := ψ.toAddHom,
                            map_smul' :=
                              (_ :
                                ∀ (r : R) (x : L),
                                  AddHom.toFun ψ.toAddHom (r • x) =
                                    (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                        y⁆) })
        ((fun χ => ↑χ) χ))
      x✝ =
    χ x✝

Next tactic:
rfl
/-- For an Abelian Lie algebra, characters are just linear forms. -/
@[simps! apply symm_apply]
def lieCharacterEquivLinearDual [IsLieAbelian L] : LieCharacter R L ≃ Module.Dual R L where
  toFun χ := (χ : L →ₗ[R] R)
  invFun ψ :=
    { ψ with
      map_lie' := fun {x y} => by
        rw [LieModule.IsTrivial.trivial, LieRing.of_associative_ring_bracket, mul_comm, sub_self,
          LinearMap.toFun_eq_coe, LinearMap.map_zero] }
  left_inv χ := by ext; rfl
  right_inv ψ := by 

Proof state:
R : Type u
L : Type v
inst✝³ : CommRing R
inst✝² : LieRing L
inst✝¹ : LieAlgebra R L
inst✝ : IsLieAbelian L
ψ : Module.Dual R L
⊢ (fun χ => ↑χ)
      ((fun ψ =>
          {
            toLinearMap :=
              { toAddHom := ψ.toAddHom,
                map_smul' :=
                  (_ :
                    ∀ (r : R) (x : L),
                      AddHom.toFun ψ.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) },
            map_lie' :=
              (_ :
                ∀ {x y : L},
                  AddHom.toFun
                      { toAddHom := ψ.toAddHom,
                          map_smul' :=
                            (_ :
                              ∀ (r : R) (x : L),
                                AddHom.toFun ψ.toAddHom (r • x) =
                                  (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                      ⁅x, y⁆ =
                    ⁅AddHom.toFun
                        { toAddHom := ψ.toAddHom,
                            map_smul' :=
                              (_ :
                                ∀ (r : R) (x : L),
                                  AddHom.toFun ψ.toAddHom (r • x) =
                                    (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                        x,
                      AddHom.toFun
                        { toAddHom := ψ.toAddHom,
                            map_smul' :=
                              (_ :
                                ∀ (r : R) (x : L),
                                  AddHom.toFun ψ.toAddHom (r • x) =
                                    (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                        y⁆) })
        ψ) =
    ψ

Next tactic:
ext
/-- For an Abelian Lie algebra, characters are just linear forms. -/
@[simps! apply symm_apply]
def lieCharacterEquivLinearDual [IsLieAbelian L] : LieCharacter R L ≃ Module.Dual R L where
  toFun χ := (χ : L →ₗ[R] R)
  invFun ψ :=
    { ψ with
      map_lie' := fun {x y} => by
        rw [LieModule.IsTrivial.trivial, LieRing.of_associative_ring_bracket, mul_comm, sub_self,
          LinearMap.toFun_eq_coe, LinearMap.map_zero] }
  left_inv χ := by ext; rfl
  right_inv ψ := by ext; 

Proof state:
case h
R : Type u
L : Type v
inst✝³ : CommRing R
inst✝² : LieRing L
inst✝¹ : LieAlgebra R L
inst✝ : IsLieAbelian L
ψ : Module.Dual R L
x✝ : L
⊢ ((fun χ => ↑χ)
        ((fun ψ =>
            {
              toLinearMap :=
                { toAddHom := ψ.toAddHom,
                  map_smul' :=
                    (_ :
                      ∀ (r : R) (x : L),
                        AddHom.toFun ψ.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) },
              map_lie' :=
                (_ :
                  ∀ {x y : L},
                    AddHom.toFun
                        { toAddHom := ψ.toAddHom,
                            map_smul' :=
                              (_ :
                                ∀ (r : R) (x : L),
                                  AddHom.toFun ψ.toAddHom (r • x) =
                                    (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                        ⁅x, y⁆ =
                      ⁅AddHom.toFun
                          { toAddHom := ψ.toAddHom,
                              map_smul' :=
                                (_ :
                                  ∀ (r : R) (x : L),
                                    AddHom.toFun ψ.toAddHom (r • x) =
                                      (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                          x,
                        AddHom.toFun
                          { toAddHom := ψ.toAddHom,
                              map_smul' :=
                                (_ :
                                  ∀ (r : R) (x : L),
                                    AddHom.toFun ψ.toAddHom (r • x) =
                                      (RingHom.id R) r • AddHom.toFun ψ.toAddHom x) }.toAddHom
                          y⁆) })
          ψ))
      x✝ =
    ψ x✝

Next tactic:
rfl
theorem Ideal.isRadical_iff_quotient_reduced {R : Type*} [CommRing R] (I : Ideal R) :
    I.IsRadical ↔ IsReduced (R ⧸ I) := by
  

Proof state:
R : Type u_1
inst✝ : CommRing R
I : Ideal R
⊢ IsRadical I ↔ IsReduced (R ⧸ I)

Next tactic:
conv_lhs => rw [← @Ideal.mk_ker R _ I]
theorem Ideal.isRadical_iff_quotient_reduced {R : Type*} [CommRing R] (I : Ideal R) :
    I.IsRadical ↔ IsReduced (R ⧸ I) := by
  conv_lhs => 

Proof state:
R : Type u_1
inst✝ : CommRing R
I : Ideal R
| IsRadical I

Next tactic:
rw [← @Ideal.mk_ker R _ I]
theorem Ideal.isRadical_iff_quotient_reduced {R : Type*} [CommRing R] (I : Ideal R) :
    I.IsRadical ↔ IsReduced (R ⧸ I) := by
  conv_lhs => rw [← @Ideal.mk_ker R _ I]
  

Proof state:
R : Type u_1
inst✝ : CommRing R
I : Ideal R
⊢ IsRadical (RingHom.ker (Quotient.mk I)) ↔ IsReduced (R ⧸ I)

Next tactic:
exact RingHom.ker_isRadical_iff_reduced_of_surjective (@Ideal.Quotient.mk_surjective R _ I)
/-- Let `P` be a property on ideals. If `P` holds for square-zero ideals, and if
  `P I → P (J ⧸ I) → P J`, then `P` holds for all nilpotent ideals. -/
theorem Ideal.IsNilpotent.induction_on (hI : IsNilpotent I)
    {P : ∀ ⦃S : Type _⦄ [CommRing S], ∀ _I : Ideal S, Prop}
    (h₁ : ∀ ⦃S : Type _⦄ [CommRing S], ∀ I : Ideal S, I ^ 2 = ⊥ → P I)
    (h₂ : ∀ ⦃S : Type _⦄ [CommRing S], ∀ I J : Ideal S, I ≤ J → P I →
      P (J.map (Ideal.Quotient.mk I)) → P J) :
    P I := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝² : CommSemiring R
inst✝¹ : CommRing S
inst✝ : Algebra R S
I : Ideal S
hI : IsNilpotent I
P : ⦃S : Type u_2⦄ → [inst : CommRing S] → Ideal S → Prop
h₁ : ∀ ⦃S : Type u_2⦄ [inst : CommRing S] (I : Ideal S), I ^ 2 = ⊥ → P I
h₂ : ∀ ⦃S : Type u_2⦄ [inst : CommRing S] (I J : Ideal S), I ≤ J → P I → P (map (Quotient.mk I) J) → P J
⊢ P I

Next tactic:
obtain ⟨n, hI : I ^ n = ⊥⟩ := hI
/-- Let `P` be a property on ideals. If `P` holds for square-zero ideals, and if
  `P I → P (J ⧸ I) → P J`, then `P` holds for all nilpotent ideals. -/
theorem Ideal.IsNilpotent.induction_on (hI : IsNilpotent I)
    {P : ∀ ⦃S : Type _⦄ [CommRing S], ∀ _I : Ideal S, Prop}
    (h₁ : ∀ ⦃S : Type _⦄ [CommRing S], ∀ I : Ideal S, I ^ 2 = ⊥ → P I)
    (h₂ : ∀ ⦃S : Type _⦄ [CommRing S], ∀ I J : Ideal S, I ≤ J → P I →
      P (J.map (Ideal.Quotient.mk I)) → P J) :
    P I := by
  obtain ⟨n, hI : I ^ n = ⊥⟩ := hI
  

Proof state:
case intro
R : Type u_1
S : Type u_2
inst✝² : CommSemiring R
inst✝¹ : CommRing S
inst✝ : Algebra R S
I : Ideal S
P : ⦃S : Type u_2⦄ → [inst : CommRing S] → Ideal S → Prop
h₁ : ∀ ⦃S : Type u_2⦄ [inst : CommRing S] (I : Ideal S), I ^ 2 = ⊥ → P I
h₂ : ∀ ⦃S : Type u_2⦄ [inst : CommRing S] (I J : Ideal S), I ≤ J → P I → P (map (Quotient.mk I) J) → P J
n : ℕ
hI : I ^ n = ⊥
⊢ P I

Next tactic:
induction' n using Nat.strong_induction_on with n H generalizing S
/-- Let `P` be a property on ideals. If `P` holds for square-zero ideals, and if
  `P I → P (J ⧸ I) → P J`, then `P` holds for all nilpotent ideals. -/
theorem Ideal.IsNilpotent.induction_on (hI : IsNilpotent I)
    {P : ∀ ⦃S : Type _⦄ [CommRing S], ∀ _I : Ideal S, Prop}
    (h₁ : ∀ ⦃S : Type _⦄ [CommRing S], ∀ I : Ideal S, I ^ 2 = ⊥ → P I)
    (h₂ : ∀ ⦃S : Type _⦄ [CommRing S], ∀ I J : Ideal S, I ≤ J → P I →
      P (J.map (Ideal.Quotient.mk I)) → P J) :
    P I := by
  obtain ⟨n, hI : I ^ n = ⊥⟩ := hI
  induction' n using Nat.strong_induction_on with n H generalizing S
  

Proof state:
case intro.h
R : Type u_1
inst✝² : CommSemiring R
P : ⦃S : Type u_2⦄ → [inst : CommRing S] → Ideal S → Prop
h₁ : ∀ ⦃S : Type u_2⦄ [inst : CommRing S] (I : Ideal S), I ^ 2 = ⊥ → P I
h₂ : ∀ ⦃S : Type u_2⦄ [inst : CommRing S] (I J : Ideal S), I ≤ J → P I → P (map (Quotient.mk I) J) → P J
n : ℕ
H : ∀ m < n, ∀ {S : Type u_2} [inst : CommRing S] [inst_1 : Algebra R S] (I : Ideal S), I ^ m = ⊥ → P I
S : Type u_2
inst✝¹ : CommRing S
inst✝ : Algebra R S
I : Ideal S
hI : I ^ n = ⊥
⊢ P I

Next tactic:
by_cases hI' : I = ⊥
/-- Let `P` be a property on ideals. If `P` holds for square-zero ideals, and if
  `P I → P (J ⧸ I) → P J`, then `P` holds for all nilpotent ideals. -/
theorem Ideal.IsNilpotent.induction_on (hI : IsNilpotent I)
    {P : ∀ ⦃S : Type _⦄ [CommRing S], ∀ _I : Ideal S, Prop}
    (h₁ : ∀ ⦃S : Type _⦄ [CommRing S], ∀ I : Ideal S, I ^ 2 = ⊥ → P I)
    (h₂ : ∀ ⦃S : Type _⦄ [CommRing S], ∀ I J : Ideal S, I ≤ J → P I →
      P (J.map (Ideal.Quotient.mk I)) → P J) :
    P I := by
  obtain ⟨n, hI : I ^ n = ⊥⟩ := hI
  induction' n using Nat.strong_induction_on with n H generalizing S
  by_cases hI' : I = ⊥
  · 

Proof state:
case pos
R : Type u_1
inst✝² : CommSemiring R
P : ⦃S : Type u_2⦄ → [inst : CommRing S] → Ideal S → Prop
h₁ : ∀ ⦃S : Type u_2⦄ [inst : CommRing S] (I : Ideal S), I ^ 2 = ⊥ → P I
h₂ : ∀ ⦃S : Type u_2⦄ [inst : CommRing S] (I J : Ideal S), I ≤ J → P I → P (map (Quotient.mk I) J) → P J
n : ℕ
H : ∀ m < n, ∀ {S : Type u_2} [inst : CommRing S] [inst_1 : Algebra R S] (I : Ideal S), I ^ m = ⊥ → P I
S : Type u_2
inst✝¹ : CommRing S
inst✝ : Algebra R S
I : Ideal S
hI : I ^ n = ⊥
hI' : I = ⊥
⊢ P I

Next tactic:
subst hI'