l3lab/ntp-mathlib huggingface dataset:
open TensorProduct LinearMap in
/-- Every `x : I ⊗ M` is the image of some `y : J ⊗ M`, where `J ≤ I` is finitely generated,
under the tensor product of `J.inclusion ‹J ≤ I› : J → I` and the identity `M → M`. -/
theorem exists_fg_le_eq_rTensor_inclusion {R M N : Type*} [CommRing R] [AddCommGroup M]
    [AddCommGroup N] [Module R M] [Module R N] {I : Submodule R N} (x : I ⊗ M) :
      ∃ (J : Submodule R N) (_ : J.FG) (hle : J ≤ I) (y : J ⊗ M),
        x = rTensor M (J.inclusion hle) y := by
  induction x using TensorProduct.induction_on with
  | zero => exact ⟨⊥, fg_bot, zero_le _, 0, rfl⟩
  | tmul i m => 

Proof state:
case tmul
R✝ : Type u_1
M✝ : Type u_2
inst✝⁹ : Semiring R✝
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
P : Type u_3
inst✝⁶ : AddCommMonoid P
inst✝⁵ : Module R✝ P
f : M✝ →ₗ[R✝] P
R : Type u_4
M : Type u_5
N : Type u_6
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : AddCommGroup N
inst✝¹ : Module R M
inst✝ : Module R N
I : Submodule R N
i : ↥I
m : M
⊢ ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, i ⊗ₜ[R] m = (rTensor M (inclusion hle)) y

Next tactic:
exact ⟨R ∙ i.val, fg_span_singleton i.val,
      (span_singleton_le_iff_mem _ _).mpr i.property,
      ⟨i.val, mem_span_singleton_self _⟩ ⊗ₜ[R] m, rfl⟩
open TensorProduct LinearMap in
/-- Every `x : I ⊗ M` is the image of some `y : J ⊗ M`, where `J ≤ I` is finitely generated,
under the tensor product of `J.inclusion ‹J ≤ I› : J → I` and the identity `M → M`. -/
theorem exists_fg_le_eq_rTensor_inclusion {R M N : Type*} [CommRing R] [AddCommGroup M]
    [AddCommGroup N] [Module R M] [Module R N] {I : Submodule R N} (x : I ⊗ M) :
      ∃ (J : Submodule R N) (_ : J.FG) (hle : J ≤ I) (y : J ⊗ M),
        x = rTensor M (J.inclusion hle) y := by
  induction x using TensorProduct.induction_on with
  | zero => exact ⟨⊥, fg_bot, zero_le _, 0, rfl⟩
  | tmul i m => exact ⟨R ∙ i.val, fg_span_singleton i.val,
      (span_singleton_le_iff_mem _ _).mpr i.property,
      ⟨i.val, mem_span_singleton_self _⟩ ⊗ₜ[R] m, rfl⟩
  

Proof state:
case add
R✝ : Type u_1
M✝ : Type u_2
inst✝⁹ : Semiring R✝
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
P : Type u_3
inst✝⁶ : AddCommMonoid P
inst✝⁵ : Module R✝ P
f : M✝ →ₗ[R✝] P
R : Type u_4
M : Type u_5
N : Type u_6
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : AddCommGroup N
inst✝¹ : Module R M
inst✝ : Module R N
I : Submodule R N
x₁ x₂ : ↥I ⊗[R] M
ihx₁ : ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, x₁ = (rTensor M (inclusion hle)) y
ihx₂ : ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, x₂ = (rTensor M (inclusion hle)) y
⊢ ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, x₁ + x₂ = (rTensor M (inclusion hle)) y

Next tactic:
| add x₁ x₂ ihx₁ ihx₂ =>
    obtain ⟨J₁, hfg₁, hle₁, y₁, rfl⟩ := ihx₁
    obtain ⟨J₂, hfg₂, hle₂, y₂, rfl⟩ := ihx₂
    refine ⟨J₁ ⊔ J₂, hfg₁.sup hfg₂, sup_le hle₁ hle₂,
      rTensor M (J₁.inclusion (le_sup_left : J₁ ≤ J₁ ⊔ J₂)) y₁ +
        rTensor M (J₂.inclusion (le_sup_right : J₂ ≤ J₁ ⊔ J₂)) y₂, ?_⟩
    rewrite [map_add, ← rTensor_comp_apply, ← rTensor_comp_apply]
    rfl
open TensorProduct LinearMap in
/-- Every `x : I ⊗ M` is the image of some `y : J ⊗ M`, where `J ≤ I` is finitely generated,
under the tensor product of `J.inclusion ‹J ≤ I› : J → I` and the identity `M → M`. -/
theorem exists_fg_le_eq_rTensor_inclusion {R M N : Type*} [CommRing R] [AddCommGroup M]
    [AddCommGroup N] [Module R M] [Module R N] {I : Submodule R N} (x : I ⊗ M) :
      ∃ (J : Submodule R N) (_ : J.FG) (hle : J ≤ I) (y : J ⊗ M),
        x = rTensor M (J.inclusion hle) y := by
  induction x using TensorProduct.induction_on with
  | zero => exact ⟨⊥, fg_bot, zero_le _, 0, rfl⟩
  | tmul i m => exact ⟨R ∙ i.val, fg_span_singleton i.val,
      (span_singleton_le_iff_mem _ _).mpr i.property,
      ⟨i.val, mem_span_singleton_self _⟩ ⊗ₜ[R] m, rfl⟩
  | add x₁ x₂ ihx₁ ihx₂ =>
    

Proof state:
case add
R✝ : Type u_1
M✝ : Type u_2
inst✝⁹ : Semiring R✝
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
P : Type u_3
inst✝⁶ : AddCommMonoid P
inst✝⁵ : Module R✝ P
f : M✝ →ₗ[R✝] P
R : Type u_4
M : Type u_5
N : Type u_6
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : AddCommGroup N
inst✝¹ : Module R M
inst✝ : Module R N
I : Submodule R N
x₁ x₂ : ↥I ⊗[R] M
ihx₁ : ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, x₁ = (rTensor M (inclusion hle)) y
ihx₂ : ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, x₂ = (rTensor M (inclusion hle)) y
⊢ ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, x₁ + x₂ = (rTensor M (inclusion hle)) y

Next tactic:
obtain ⟨J₁, hfg₁, hle₁, y₁, rfl⟩ := ihx₁
open TensorProduct LinearMap in
/-- Every `x : I ⊗ M` is the image of some `y : J ⊗ M`, where `J ≤ I` is finitely generated,
under the tensor product of `J.inclusion ‹J ≤ I› : J → I` and the identity `M → M`. -/
theorem exists_fg_le_eq_rTensor_inclusion {R M N : Type*} [CommRing R] [AddCommGroup M]
    [AddCommGroup N] [Module R M] [Module R N] {I : Submodule R N} (x : I ⊗ M) :
      ∃ (J : Submodule R N) (_ : J.FG) (hle : J ≤ I) (y : J ⊗ M),
        x = rTensor M (J.inclusion hle) y := by
  induction x using TensorProduct.induction_on with
  | zero => exact ⟨⊥, fg_bot, zero_le _, 0, rfl⟩
  | tmul i m => exact ⟨R ∙ i.val, fg_span_singleton i.val,
      (span_singleton_le_iff_mem _ _).mpr i.property,
      ⟨i.val, mem_span_singleton_self _⟩ ⊗ₜ[R] m, rfl⟩
  | add x₁ x₂ ihx₁ ihx₂ =>
    obtain ⟨J₁, hfg₁, hle₁, y₁, rfl⟩ := ihx₁
    

Proof state:
case add.intro.intro.intro.intro
R✝ : Type u_1
M✝ : Type u_2
inst✝⁹ : Semiring R✝
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
P : Type u_3
inst✝⁶ : AddCommMonoid P
inst✝⁵ : Module R✝ P
f : M✝ →ₗ[R✝] P
R : Type u_4
M : Type u_5
N : Type u_6
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : AddCommGroup N
inst✝¹ : Module R M
inst✝ : Module R N
I : Submodule R N
x₂ : ↥I ⊗[R] M
ihx₂ : ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, x₂ = (rTensor M (inclusion hle)) y
J₁ : Submodule R N
hfg₁ : FG J₁
hle₁ : J₁ ≤ I
y₁ : ↥J₁ ⊗[R] M
⊢ ∃ J, ∃ (_ : FG J) (hle : J ≤ I), ∃ y, (rTensor M (inclusion hle₁)) y₁ + x₂ = (rTensor M (inclusion hle)) y

Next tactic:
obtain ⟨J₂, hfg₂, hle₂, y₂, rfl⟩ := ihx₂
open TensorProduct LinearMap in
/-- Every `x : I ⊗ M` is the image of some `y : J ⊗ M`, where `J ≤ I` is finitely generated,
under the tensor product of `J.inclusion ‹J ≤ I› : J → I` and the identity `M → M`. -/
theorem exists_fg_le_eq_rTensor_inclusion {R M N : Type*} [CommRing R] [AddCommGroup M]
    [AddCommGroup N] [Module R M] [Module R N] {I : Submodule R N} (x : I ⊗ M) :
      ∃ (J : Submodule R N) (_ : J.FG) (hle : J ≤ I) (y : J ⊗ M),
        x = rTensor M (J.inclusion hle) y := by
  induction x using TensorProduct.induction_on with
  | zero => exact ⟨⊥, fg_bot, zero_le _, 0, rfl⟩
  | tmul i m => exact ⟨R ∙ i.val, fg_span_singleton i.val,
      (span_singleton_le_iff_mem _ _).mpr i.property,
      ⟨i.val, mem_span_singleton_self _⟩ ⊗ₜ[R] m, rfl⟩
  | add x₁ x₂ ihx₁ ihx₂ =>
    obtain ⟨J₁, hfg₁, hle₁, y₁, rfl⟩ := ihx₁
    obtain ⟨J₂, hfg₂, hle₂, y₂, rfl⟩ := ihx₂
    

Proof state:
case add.intro.intro.intro.intro.intro.intro.intro.intro
R✝ : Type u_1
M✝ : Type u_2
inst✝⁹ : Semiring R✝
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
P : Type u_3
inst✝⁶ : AddCommMonoid P
inst✝⁵ : Module R✝ P
f : M✝ →ₗ[R✝] P
R : Type u_4
M : Type u_5
N : Type u_6
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : AddCommGroup N
inst✝¹ : Module R M
inst✝ : Module R N
I J₁ : Submodule R N
hfg₁ : FG J₁
hle₁ : J₁ ≤ I
y₁ : ↥J₁ ⊗[R] M
J₂ : Submodule R N
hfg₂ : FG J₂
hle₂ : J₂ ≤ I
y₂ : ↥J₂ ⊗[R] M
⊢ ∃ J,
    ∃ (_ : FG J) (hle : J ≤ I),
      ∃ y, (rTensor M (inclusion hle₁)) y₁ + (rTensor M (inclusion hle₂)) y₂ = (rTensor M (inclusion hle)) y

Next tactic:
refine ⟨J₁ ⊔ J₂, hfg₁.sup hfg₂, sup_le hle₁ hle₂,
      rTensor M (J₁.inclusion (le_sup_left : J₁ ≤ J₁ ⊔ J₂)) y₁ +
        rTensor M (J₂.inclusion (le_sup_right : J₂ ≤ J₁ ⊔ J₂)) y₂, ?_⟩
open TensorProduct LinearMap in
/-- Every `x : I ⊗ M` is the image of some `y : J ⊗ M`, where `J ≤ I` is finitely generated,
under the tensor product of `J.inclusion ‹J ≤ I› : J → I` and the identity `M → M`. -/
theorem exists_fg_le_eq_rTensor_inclusion {R M N : Type*} [CommRing R] [AddCommGroup M]
    [AddCommGroup N] [Module R M] [Module R N] {I : Submodule R N} (x : I ⊗ M) :
      ∃ (J : Submodule R N) (_ : J.FG) (hle : J ≤ I) (y : J ⊗ M),
        x = rTensor M (J.inclusion hle) y := by
  induction x using TensorProduct.induction_on with
  | zero => exact ⟨⊥, fg_bot, zero_le _, 0, rfl⟩
  | tmul i m => exact ⟨R ∙ i.val, fg_span_singleton i.val,
      (span_singleton_le_iff_mem _ _).mpr i.property,
      ⟨i.val, mem_span_singleton_self _⟩ ⊗ₜ[R] m, rfl⟩
  | add x₁ x₂ ihx₁ ihx₂ =>
    obtain ⟨J₁, hfg₁, hle₁, y₁, rfl⟩ := ihx₁
    obtain ⟨J₂, hfg₂, hle₂, y₂, rfl⟩ := ihx₂
    refine ⟨J₁ ⊔ J₂, hfg₁.sup hfg₂, sup_le hle₁ hle₂,
      rTensor M (J₁.inclusion (le_sup_left : J₁ ≤ J₁ ⊔ J₂)) y₁ +
        rTensor M (J₂.inclusion (le_sup_right : J₂ ≤ J₁ ⊔ J₂)) y₂, ?_⟩
    

Proof state:
case add.intro.intro.intro.intro.intro.intro.intro.intro
R✝ : Type u_1
M✝ : Type u_2
inst✝⁹ : Semiring R✝
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
P : Type u_3
inst✝⁶ : AddCommMonoid P
inst✝⁵ : Module R✝ P
f : M✝ →ₗ[R✝] P
R : Type u_4
M : Type u_5
N : Type u_6
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : AddCommGroup N
inst✝¹ : Module R M
inst✝ : Module R N
I J₁ : Submodule R N
hfg₁ : FG J₁
hle₁ : J₁ ≤ I
y₁ : ↥J₁ ⊗[R] M
J₂ : Submodule R N
hfg₂ : FG J₂
hle₂ : J₂ ≤ I
y₂ : ↥J₂ ⊗[R] M
⊢ (rTensor M (inclusion hle₁)) y₁ + (rTensor M (inclusion hle₂)) y₂ =
    (rTensor M (inclusion (_ : J₁ ⊔ J₂ ≤ I)))
      ((rTensor M (inclusion (_ : J₁ ≤ J₁ ⊔ J₂))) y₁ + (rTensor M (inclusion (_ : J₂ ≤ J₁ ⊔ J₂))) y₂)

Next tactic:
rewrite [map_add, ← rTensor_comp_apply, ← rTensor_comp_apply]
open TensorProduct LinearMap in
/-- Every `x : I ⊗ M` is the image of some `y : J ⊗ M`, where `J ≤ I` is finitely generated,
under the tensor product of `J.inclusion ‹J ≤ I› : J → I` and the identity `M → M`. -/
theorem exists_fg_le_eq_rTensor_inclusion {R M N : Type*} [CommRing R] [AddCommGroup M]
    [AddCommGroup N] [Module R M] [Module R N] {I : Submodule R N} (x : I ⊗ M) :
      ∃ (J : Submodule R N) (_ : J.FG) (hle : J ≤ I) (y : J ⊗ M),
        x = rTensor M (J.inclusion hle) y := by
  induction x using TensorProduct.induction_on with
  | zero => exact ⟨⊥, fg_bot, zero_le _, 0, rfl⟩
  | tmul i m => exact ⟨R ∙ i.val, fg_span_singleton i.val,
      (span_singleton_le_iff_mem _ _).mpr i.property,
      ⟨i.val, mem_span_singleton_self _⟩ ⊗ₜ[R] m, rfl⟩
  | add x₁ x₂ ihx₁ ihx₂ =>
    obtain ⟨J₁, hfg₁, hle₁, y₁, rfl⟩ := ihx₁
    obtain ⟨J₂, hfg₂, hle₂, y₂, rfl⟩ := ihx₂
    refine ⟨J₁ ⊔ J₂, hfg₁.sup hfg₂, sup_le hle₁ hle₂,
      rTensor M (J₁.inclusion (le_sup_left : J₁ ≤ J₁ ⊔ J₂)) y₁ +
        rTensor M (J₂.inclusion (le_sup_right : J₂ ≤ J₁ ⊔ J₂)) y₂, ?_⟩
    rewrite [map_add, ← rTensor_comp_apply, ← rTensor_comp_apply]
    

Proof state:
case add.intro.intro.intro.intro.intro.intro.intro.intro
R✝ : Type u_1
M✝ : Type u_2
inst✝⁹ : Semiring R✝
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
P : Type u_3
inst✝⁶ : AddCommMonoid P
inst✝⁵ : Module R✝ P
f : M✝ →ₗ[R✝] P
R : Type u_4
M : Type u_5
N : Type u_6
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : AddCommGroup N
inst✝¹ : Module R M
inst✝ : Module R N
I J₁ : Submodule R N
hfg₁ : FG J₁
hle₁ : J₁ ≤ I
y₁ : ↥J₁ ⊗[R] M
J₂ : Submodule R N
hfg₂ : FG J₂
hle₂ : J₂ ≤ I
y₂ : ↥J₂ ⊗[R] M
⊢ (rTensor M (inclusion hle₁)) y₁ + (rTensor M (inclusion hle₂)) y₂ =
    (rTensor M (inclusion (_ : J₁ ⊔ J₂ ≤ I) ∘ₗ inclusion (_ : J₁ ≤ J₁ ⊔ J₂))) y₁ +
      (rTensor M (inclusion (_ : J₁ ⊔ J₂ ≤ I) ∘ₗ inclusion (_ : J₂ ≤ J₁ ⊔ J₂))) y₂

Next tactic:
rfl
theorem FG.pow (h : M.FG) (n : ℕ) : (M ^ n).FG :=
  Nat.recOn n ⟨{1}, by 

Proof state:
R : Type u_1
A : Type u_2
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Algebra R A
M N : Submodule R A
h : FG M
n : ℕ
⊢ span R ↑{1} = M ^ Nat.zero

Next tactic:
simp [one_eq_span]
theorem FG.pow (h : M.FG) (n : ℕ) : (M ^ n).FG :=
  Nat.recOn n ⟨{1}, by simp [one_eq_span]⟩ fun n ih => by 

Proof state:
R : Type u_1
A : Type u_2
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Algebra R A
M N : Submodule R A
h : FG M
n✝ n : ℕ
ih : FG (M ^ n)
⊢ FG (M ^ Nat.succ n)

Next tactic:
simpa [pow_succ] using h.mul ih
/-- The image of a finitely generated ideal is finitely generated.

This is the `Ideal` version of `Submodule.FG.map`. -/
theorem FG.map {R S : Type*} [Semiring R] [Semiring S] {I : Ideal R} (h : I.FG) (f : R →+* S) :
    (I.map f).FG := by
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁴ : Semiring R✝
inst✝³ : AddCommMonoid M
inst✝² : Module R✝ M
R : Type u_3
S : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
I : Ideal R
h : FG I
f : R →+* S
⊢ FG (Ideal.map f I)

Next tactic:
classical
    obtain ⟨s, hs⟩ := h
    refine' ⟨s.image f, _⟩
    rw [Finset.coe_image, ← Ideal.map_span, hs]
/-- The image of a finitely generated ideal is finitely generated.

This is the `Ideal` version of `Submodule.FG.map`. -/
theorem FG.map {R S : Type*} [Semiring R] [Semiring S] {I : Ideal R} (h : I.FG) (f : R →+* S) :
    (I.map f).FG := by
  classical
    

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁴ : Semiring R✝
inst✝³ : AddCommMonoid M
inst✝² : Module R✝ M
R : Type u_3
S : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
I : Ideal R
h : FG I
f : R →+* S
⊢ FG (Ideal.map f I)

Next tactic:
obtain ⟨s, hs⟩ := h
/-- The image of a finitely generated ideal is finitely generated.

This is the `Ideal` version of `Submodule.FG.map`. -/
theorem FG.map {R S : Type*} [Semiring R] [Semiring S] {I : Ideal R} (h : I.FG) (f : R →+* S) :
    (I.map f).FG := by
  classical
    obtain ⟨s, hs⟩ := h
    

Proof state:
case intro
R✝ : Type u_1
M : Type u_2
inst✝⁴ : Semiring R✝
inst✝³ : AddCommMonoid M
inst✝² : Module R✝ M
R : Type u_3
S : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
I : Ideal R
f : R →+* S
s : Finset R
hs : span ↑s = I
⊢ FG (Ideal.map f I)

Next tactic:
refine' ⟨s.image f, _⟩
/-- The image of a finitely generated ideal is finitely generated.

This is the `Ideal` version of `Submodule.FG.map`. -/
theorem FG.map {R S : Type*} [Semiring R] [Semiring S] {I : Ideal R} (h : I.FG) (f : R →+* S) :
    (I.map f).FG := by
  classical
    obtain ⟨s, hs⟩ := h
    refine' ⟨s.image f, _⟩
    

Proof state:
case intro
R✝ : Type u_1
M : Type u_2
inst✝⁴ : Semiring R✝
inst✝³ : AddCommMonoid M
inst✝² : Module R✝ M
R : Type u_3
S : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
I : Ideal R
f : R →+* S
s : Finset R
hs : span ↑s = I
⊢ span ↑(Finset.image (⇑f) s) = Ideal.map f I

Next tactic:
rw [Finset.coe_image, ← Ideal.map_span, hs]
theorem fg_ker_comp {R S A : Type*} [CommRing R] [CommRing S] [CommRing A] (f : R →+* S)
    (g : S →+* A) (hf : f.ker.FG) (hg : g.ker.FG) (hsur : Function.Surjective f) :
    (g.comp f).ker.FG := by
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁵ : Semiring R✝
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R✝ M
R : Type u_3
S : Type u_4
A : Type u_5
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : CommRing A
f : R →+* S
g : S →+* A
hf : FG (RingHom.ker f)
hg : FG (RingHom.ker g)
hsur : Surjective ⇑f
⊢ FG (RingHom.ker (RingHom.comp g f))

Next tactic:
letI : Algebra R S := RingHom.toAlgebra f
theorem fg_ker_comp {R S A : Type*} [CommRing R] [CommRing S] [CommRing A] (f : R →+* S)
    (g : S →+* A) (hf : f.ker.FG) (hg : g.ker.FG) (hsur : Function.Surjective f) :
    (g.comp f).ker.FG := by
  letI : Algebra R S := RingHom.toAlgebra f
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁵ : Semiring R✝
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R✝ M
R : Type u_3
S : Type u_4
A : Type u_5
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : CommRing A
f : R →+* S
g : S →+* A
hf : FG (RingHom.ker f)
hg : FG (RingHom.ker g)
hsur : Surjective ⇑f
this : Algebra R S := RingHom.toAlgebra f
⊢ FG (RingHom.ker (RingHom.comp g f))

Next tactic:
letI : Algebra R A := RingHom.toAlgebra (g.comp f)
theorem fg_ker_comp {R S A : Type*} [CommRing R] [CommRing S] [CommRing A] (f : R →+* S)
    (g : S →+* A) (hf : f.ker.FG) (hg : g.ker.FG) (hsur : Function.Surjective f) :
    (g.comp f).ker.FG := by
  letI : Algebra R S := RingHom.toAlgebra f
  letI : Algebra R A := RingHom.toAlgebra (g.comp f)
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁵ : Semiring R✝
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R✝ M
R : Type u_3
S : Type u_4
A : Type u_5
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : CommRing A
f : R →+* S
g : S →+* A
hf : FG (RingHom.ker f)
hg : FG (RingHom.ker g)
hsur : Surjective ⇑f
this✝ : Algebra R S := RingHom.toAlgebra f
this : Algebra R A := RingHom.toAlgebra (RingHom.comp g f)
⊢ FG (RingHom.ker (RingHom.comp g f))

Next tactic:
letI : Algebra S A := RingHom.toAlgebra g
theorem fg_ker_comp {R S A : Type*} [CommRing R] [CommRing S] [CommRing A] (f : R →+* S)
    (g : S →+* A) (hf : f.ker.FG) (hg : g.ker.FG) (hsur : Function.Surjective f) :
    (g.comp f).ker.FG := by
  letI : Algebra R S := RingHom.toAlgebra f
  letI : Algebra R A := RingHom.toAlgebra (g.comp f)
  letI : Algebra S A := RingHom.toAlgebra g
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁵ : Semiring R✝
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R✝ M
R : Type u_3
S : Type u_4
A : Type u_5
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : CommRing A
f : R →+* S
g : S →+* A
hf : FG (RingHom.ker f)
hg : FG (RingHom.ker g)
hsur : Surjective ⇑f
this✝¹ : Algebra R S := RingHom.toAlgebra f
this✝ : Algebra R A := RingHom.toAlgebra (RingHom.comp g f)
this : Algebra S A := RingHom.toAlgebra g
⊢ FG (RingHom.ker (RingHom.comp g f))

Next tactic:
letI : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun _ => rfl
theorem fg_ker_comp {R S A : Type*} [CommRing R] [CommRing S] [CommRing A] (f : R →+* S)
    (g : S →+* A) (hf : f.ker.FG) (hg : g.ker.FG) (hsur : Function.Surjective f) :
    (g.comp f).ker.FG := by
  letI : Algebra R S := RingHom.toAlgebra f
  letI : Algebra R A := RingHom.toAlgebra (g.comp f)
  letI : Algebra S A := RingHom.toAlgebra g
  letI : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun _ => rfl
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁵ : Semiring R✝
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R✝ M
R : Type u_3
S : Type u_4
A : Type u_5
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : CommRing A
f : R →+* S
g : S →+* A
hf : FG (RingHom.ker f)
hg : FG (RingHom.ker g)
hsur : Surjective ⇑f
this✝² : Algebra R S := RingHom.toAlgebra f
this✝¹ : Algebra R A := RingHom.toAlgebra (RingHom.comp g f)
this✝ : Algebra S A := RingHom.toAlgebra g
this : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun x => rfl
⊢ FG (RingHom.ker (RingHom.comp g f))

Next tactic:
let f₁ := Algebra.linearMap R S
theorem fg_ker_comp {R S A : Type*} [CommRing R] [CommRing S] [CommRing A] (f : R →+* S)
    (g : S →+* A) (hf : f.ker.FG) (hg : g.ker.FG) (hsur : Function.Surjective f) :
    (g.comp f).ker.FG := by
  letI : Algebra R S := RingHom.toAlgebra f
  letI : Algebra R A := RingHom.toAlgebra (g.comp f)
  letI : Algebra S A := RingHom.toAlgebra g
  letI : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun _ => rfl
  let f₁ := Algebra.linearMap R S
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁵ : Semiring R✝
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R✝ M
R : Type u_3
S : Type u_4
A : Type u_5
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : CommRing A
f : R →+* S
g : S →+* A
hf : FG (RingHom.ker f)
hg : FG (RingHom.ker g)
hsur : Surjective ⇑f
this✝² : Algebra R S := RingHom.toAlgebra f
this✝¹ : Algebra R A := RingHom.toAlgebra (RingHom.comp g f)
this✝ : Algebra S A := RingHom.toAlgebra g
this : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun x => rfl
f₁ : R →ₗ[R] S := Algebra.linearMap R S
⊢ FG (RingHom.ker (RingHom.comp g f))

Next tactic:
let g₁ := (IsScalarTower.toAlgHom R S A).toLinearMap
theorem fg_ker_comp {R S A : Type*} [CommRing R] [CommRing S] [CommRing A] (f : R →+* S)
    (g : S →+* A) (hf : f.ker.FG) (hg : g.ker.FG) (hsur : Function.Surjective f) :
    (g.comp f).ker.FG := by
  letI : Algebra R S := RingHom.toAlgebra f
  letI : Algebra R A := RingHom.toAlgebra (g.comp f)
  letI : Algebra S A := RingHom.toAlgebra g
  letI : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun _ => rfl
  let f₁ := Algebra.linearMap R S
  let g₁ := (IsScalarTower.toAlgHom R S A).toLinearMap
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝⁵ : Semiring R✝
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R✝ M
R : Type u_3
S : Type u_4
A : Type u_5
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : CommRing A
f : R →+* S
g : S →+* A
hf : FG (RingHom.ker f)
hg : FG (RingHom.ker g)
hsur : Surjective ⇑f
this✝² : Algebra R S := RingHom.toAlgebra f
this✝¹ : Algebra R A := RingHom.toAlgebra (RingHom.comp g f)
this✝ : Algebra S A := RingHom.toAlgebra g
this : IsScalarTower R S A := IsScalarTower.of_algebraMap_eq fun x => rfl
f₁ : R →ₗ[R] S := Algebra.linearMap R S
g₁ : S →ₗ[R] A := AlgHom.toLinearMap (IsScalarTower.toAlgHom R S A)
⊢ FG (RingHom.ker (RingHom.comp g f))

Next tactic:
exact Submodule.fg_ker_comp f₁ g₁ hf (Submodule.fg_restrictScalars (RingHom.ker g) hg hsur) hsur
theorem exists_radical_pow_le_of_fg {R : Type*} [CommSemiring R] (I : Ideal R) (h : I.radical.FG) :
    ∃ n : ℕ, I.radical ^ n ≤ I := by
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
⊢ ∃ n, radical I ^ n ≤ I

Next tactic:
have := le_refl I.radical
theorem exists_radical_pow_le_of_fg {R : Type*} [CommSemiring R] (I : Ideal R) (h : I.radical.FG) :
    ∃ n : ℕ, I.radical ^ n ≤ I := by
  have := le_refl I.radical; 

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
this : radical I ≤ radical I
⊢ ∃ n, radical I ^ n ≤ I

Next tactic:
revert this
theorem exists_radical_pow_le_of_fg {R : Type*} [CommSemiring R] (I : Ideal R) (h : I.radical.FG) :
    ∃ n : ℕ, I.radical ^ n ≤ I := by
  have := le_refl I.radical; revert this
  

Proof state:
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
⊢ radical I ≤ radical I → ∃ n, radical I ^ n ≤ I

Next tactic:
refine' Submodule.fg_induction _ _ (fun J => J ≤ I.radical → ∃ n : ℕ, J ^ n ≤ I) _ _ _ h
theorem exists_radical_pow_le_of_fg {R : Type*} [CommSemiring R] (I : Ideal R) (h : I.radical.FG) :
    ∃ n : ℕ, I.radical ^ n ≤ I := by
  have := le_refl I.radical; revert this
  refine' Submodule.fg_induction _ _ (fun J => J ≤ I.radical → ∃ n : ℕ, J ^ n ≤ I) _ _ _ h
  · 

Proof state:
case refine'_1
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
⊢ ∀ (x : R), (fun J => J ≤ radical I → ∃ n, J ^ n ≤ I) (Submodule.span R {x})

Next tactic:
intro x hx
theorem exists_radical_pow_le_of_fg {R : Type*} [CommSemiring R] (I : Ideal R) (h : I.radical.FG) :
    ∃ n : ℕ, I.radical ^ n ≤ I := by
  have := le_refl I.radical; revert this
  refine' Submodule.fg_induction _ _ (fun J => J ≤ I.radical → ∃ n : ℕ, J ^ n ≤ I) _ _ _ h
  · intro x hx
    

Proof state:
case refine'_1
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
x : R
hx : Submodule.span R {x} ≤ radical I
⊢ ∃ n, Submodule.span R {x} ^ n ≤ I

Next tactic:
obtain ⟨n, hn⟩ := hx (subset_span (Set.mem_singleton x))
theorem exists_radical_pow_le_of_fg {R : Type*} [CommSemiring R] (I : Ideal R) (h : I.radical.FG) :
    ∃ n : ℕ, I.radical ^ n ≤ I := by
  have := le_refl I.radical; revert this
  refine' Submodule.fg_induction _ _ (fun J => J ≤ I.radical → ∃ n : ℕ, J ^ n ≤ I) _ _ _ h
  · intro x hx
    obtain ⟨n, hn⟩ := hx (subset_span (Set.mem_singleton x))
    

Proof state:
case refine'_1.intro
R✝ : Type u_1
M : Type u_2
inst✝³ : Semiring R✝
inst✝² : AddCommMonoid M
inst✝¹ : Module R✝ M
R : Type u_3
inst✝ : CommSemiring R
I : Ideal R
h : FG (radical I)
x : R
hx : Submodule.span R {x} ≤ radical I
n : ℕ
hn : x ^ n ∈ I
⊢ ∃ n, Submodule.span R {x} ^ n ≤ I

Next tactic:
exact ⟨n, by rwa [← Ideal.span, span_singleton_pow, span_le, Set.singleton_subset_iff]⟩