l3lab/ntp-mathlib huggingface dataset:
instance isNoetherian_pi {R ι : Type*} {M : ι → Type*}
    [Ring R] [∀ i, AddCommGroup (M i)] [∀ i, Module R (M i)] [Finite ι]
    [∀ i, IsNoetherian R (M i)] : IsNoetherian R (∀ i, M i) := by
  cases nonempty_fintype ι
  haveI := Classical.decEq ι
  suffices on_finset : ∀ s : Finset ι, IsNoetherian R (∀ i : s, M i)
  · let coe_e := Equiv.subtypeUnivEquiv <| @Finset.mem_univ ι _
    letI : IsNoetherian R (∀ i : Finset.univ, M (coe_e i)) := on_finset Finset.univ
    exact isNoetherian_of_linearEquiv (LinearEquiv.piCongrLeft R M coe_e)
  intro s
  induction' s using Finset.induction with a s has ih
  · exact ⟨fun s => by
      have : s = ⊥ := by simp only [eq_iff_true_of_subsingleton]
      rw [this]
      apply Submodule.fg_bot⟩
  refine
    @isNoetherian_of_linearEquiv R (M a × ((i : s) → M i)) _ _ _ _ _ _ ?_ <|
      @isNoetherian_prod R (M a) _ _ _ _ _ _ _ ih
  refine
  { toFun := fun f i =>
      (Finset.mem_insert.1 i.2).by_cases
        (fun h : i.1 = a => show M i.1 from Eq.recOn h.symm f.1)
        (fun h : i.1 ∈ s => show M i.1 from f.2 ⟨i.1, h⟩),
    invFun := fun f =>
      (f ⟨a, Finset.mem_insert_self _ _⟩, fun i => f ⟨i.1, Finset.mem_insert_of_mem i.2⟩),
    map_add' := ?_,
    map_smul' := ?_
    left_inv := ?_,
    right_inv := ?_ }
  · intro f g
    ext i
    unfold Or.by_cases
    cases' i with i hi
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · change _ = _ + _
      simp only [dif_pos]
      rfl
    · change _ = _ + _
      have : ¬i = a := by
        rintro rfl
        exact has h
      simp only [dif_neg this, dif_pos h]
      rfl
  · intro c f
    ext i
    unfold Or.by_cases
    cases' i with i hi
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · dsimp
      simp only [dif_pos]
    · dsimp
      have : ¬i = a := by
        rintro rfl
        exact has h
      simp only [dif_neg this, dif_pos h]
  · intro f
    apply Prod.ext
    · simp only [Or.by_cases, dif_pos]
    · ext ⟨i, his⟩
      have : ¬i = a := by
        

Proof state:
R✝ : Type u_1
M✝ : Type u_2
P : Type u_3
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R✝ M✝
inst✝⁵ : Module R✝ P
R : Type u_4
ι : Type u_5
M : ι → Type u_6
inst✝⁴ : Ring R
inst✝³ : (i : ι) → AddCommGroup (M i)
inst✝² : (i : ι) → Module R (M i)
inst✝¹ : Finite ι
inst✝ : ∀ (i : ι), IsNoetherian R (M i)
val✝ : Fintype ι
this : DecidableEq ι
a : ι
s : Finset ι
has : a ∉ s
ih : IsNoetherian R ((i : { x // x ∈ s }) → M ↑i)
f : M a × ((i : { x // x ∈ s }) → M ↑i)
i : ι
his : i ∈ s
⊢ ¬i = a

Next tactic:
rintro rfl
instance isNoetherian_pi {R ι : Type*} {M : ι → Type*}
    [Ring R] [∀ i, AddCommGroup (M i)] [∀ i, Module R (M i)] [Finite ι]
    [∀ i, IsNoetherian R (M i)] : IsNoetherian R (∀ i, M i) := by
  cases nonempty_fintype ι
  haveI := Classical.decEq ι
  suffices on_finset : ∀ s : Finset ι, IsNoetherian R (∀ i : s, M i)
  · let coe_e := Equiv.subtypeUnivEquiv <| @Finset.mem_univ ι _
    letI : IsNoetherian R (∀ i : Finset.univ, M (coe_e i)) := on_finset Finset.univ
    exact isNoetherian_of_linearEquiv (LinearEquiv.piCongrLeft R M coe_e)
  intro s
  induction' s using Finset.induction with a s has ih
  · exact ⟨fun s => by
      have : s = ⊥ := by simp only [eq_iff_true_of_subsingleton]
      rw [this]
      apply Submodule.fg_bot⟩
  refine
    @isNoetherian_of_linearEquiv R (M a × ((i : s) → M i)) _ _ _ _ _ _ ?_ <|
      @isNoetherian_prod R (M a) _ _ _ _ _ _ _ ih
  refine
  { toFun := fun f i =>
      (Finset.mem_insert.1 i.2).by_cases
        (fun h : i.1 = a => show M i.1 from Eq.recOn h.symm f.1)
        (fun h : i.1 ∈ s => show M i.1 from f.2 ⟨i.1, h⟩),
    invFun := fun f =>
      (f ⟨a, Finset.mem_insert_self _ _⟩, fun i => f ⟨i.1, Finset.mem_insert_of_mem i.2⟩),
    map_add' := ?_,
    map_smul' := ?_
    left_inv := ?_,
    right_inv := ?_ }
  · intro f g
    ext i
    unfold Or.by_cases
    cases' i with i hi
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · change _ = _ + _
      simp only [dif_pos]
      rfl
    · change _ = _ + _
      have : ¬i = a := by
        rintro rfl
        exact has h
      simp only [dif_neg this, dif_pos h]
      rfl
  · intro c f
    ext i
    unfold Or.by_cases
    cases' i with i hi
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · dsimp
      simp only [dif_pos]
    · dsimp
      have : ¬i = a := by
        rintro rfl
        exact has h
      simp only [dif_neg this, dif_pos h]
  · intro f
    apply Prod.ext
    · simp only [Or.by_cases, dif_pos]
    · ext ⟨i, his⟩
      have : ¬i = a := by
        rintro rfl
        

Proof state:
R✝ : Type u_1
M✝ : Type u_2
P : Type u_3
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R✝ M✝
inst✝⁵ : Module R✝ P
R : Type u_4
ι : Type u_5
M : ι → Type u_6
inst✝⁴ : Ring R
inst✝³ : (i : ι) → AddCommGroup (M i)
inst✝² : (i : ι) → Module R (M i)
inst✝¹ : Finite ι
inst✝ : ∀ (i : ι), IsNoetherian R (M i)
val✝ : Fintype ι
this : DecidableEq ι
s : Finset ι
ih : IsNoetherian R ((i : { x // x ∈ s }) → M ↑i)
i : ι
his : i ∈ s
has : i ∉ s
f : M i × ((i : { x // x ∈ s }) → M ↑i)
⊢ False

Next tactic:
exact has his
instance isNoetherian_pi {R ι : Type*} {M : ι → Type*}
    [Ring R] [∀ i, AddCommGroup (M i)] [∀ i, Module R (M i)] [Finite ι]
    [∀ i, IsNoetherian R (M i)] : IsNoetherian R (∀ i, M i) := by
  cases nonempty_fintype ι
  haveI := Classical.decEq ι
  suffices on_finset : ∀ s : Finset ι, IsNoetherian R (∀ i : s, M i)
  · let coe_e := Equiv.subtypeUnivEquiv <| @Finset.mem_univ ι _
    letI : IsNoetherian R (∀ i : Finset.univ, M (coe_e i)) := on_finset Finset.univ
    exact isNoetherian_of_linearEquiv (LinearEquiv.piCongrLeft R M coe_e)
  intro s
  induction' s using Finset.induction with a s has ih
  · exact ⟨fun s => by
      have : s = ⊥ := by simp only [eq_iff_true_of_subsingleton]
      rw [this]
      apply Submodule.fg_bot⟩
  refine
    @isNoetherian_of_linearEquiv R (M a × ((i : s) → M i)) _ _ _ _ _ _ ?_ <|
      @isNoetherian_prod R (M a) _ _ _ _ _ _ _ ih
  refine
  { toFun := fun f i =>
      (Finset.mem_insert.1 i.2).by_cases
        (fun h : i.1 = a => show M i.1 from Eq.recOn h.symm f.1)
        (fun h : i.1 ∈ s => show M i.1 from f.2 ⟨i.1, h⟩),
    invFun := fun f =>
      (f ⟨a, Finset.mem_insert_self _ _⟩, fun i => f ⟨i.1, Finset.mem_insert_of_mem i.2⟩),
    map_add' := ?_,
    map_smul' := ?_
    left_inv := ?_,
    right_inv := ?_ }
  · intro f g
    ext i
    unfold Or.by_cases
    cases' i with i hi
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · change _ = _ + _
      simp only [dif_pos]
      rfl
    · change _ = _ + _
      have : ¬i = a := by
        rintro rfl
        exact has h
      simp only [dif_neg this, dif_pos h]
      rfl
  · intro c f
    ext i
    unfold Or.by_cases
    cases' i with i hi
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · dsimp
      simp only [dif_pos]
    · dsimp
      have : ¬i = a := by
        rintro rfl
        exact has h
      simp only [dif_neg this, dif_pos h]
  · intro f
    apply Prod.ext
    · simp only [Or.by_cases, dif_pos]
    · ext ⟨i, his⟩
      have : ¬i = a := by
        rintro rfl
        exact has his
      simp only [Or.by_cases, this, not_false_iff, dif_neg]
  · intro f
    ext ⟨i, hi⟩
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · simp only [Or.by_cases, dif_pos]
    · have : ¬i = a := by
        

Proof state:
R✝ : Type u_1
M✝ : Type u_2
P : Type u_3
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R✝ M✝
inst✝⁵ : Module R✝ P
R : Type u_4
ι : Type u_5
M : ι → Type u_6
inst✝⁴ : Ring R
inst✝³ : (i : ι) → AddCommGroup (M i)
inst✝² : (i : ι) → Module R (M i)
inst✝¹ : Finite ι
inst✝ : ∀ (i : ι), IsNoetherian R (M i)
val✝ : Fintype ι
this : DecidableEq ι
a : ι
s : Finset ι
has : a ∉ s
ih : IsNoetherian R ((i : { x // x ∈ s }) → M ↑i)
f : (i : { x // x ∈ insert a s }) → M ↑i
i : ι
hi : i ∈ insert a s
h : i ∈ s
⊢ ¬i = a

Next tactic:
rintro rfl
instance isNoetherian_pi {R ι : Type*} {M : ι → Type*}
    [Ring R] [∀ i, AddCommGroup (M i)] [∀ i, Module R (M i)] [Finite ι]
    [∀ i, IsNoetherian R (M i)] : IsNoetherian R (∀ i, M i) := by
  cases nonempty_fintype ι
  haveI := Classical.decEq ι
  suffices on_finset : ∀ s : Finset ι, IsNoetherian R (∀ i : s, M i)
  · let coe_e := Equiv.subtypeUnivEquiv <| @Finset.mem_univ ι _
    letI : IsNoetherian R (∀ i : Finset.univ, M (coe_e i)) := on_finset Finset.univ
    exact isNoetherian_of_linearEquiv (LinearEquiv.piCongrLeft R M coe_e)
  intro s
  induction' s using Finset.induction with a s has ih
  · exact ⟨fun s => by
      have : s = ⊥ := by simp only [eq_iff_true_of_subsingleton]
      rw [this]
      apply Submodule.fg_bot⟩
  refine
    @isNoetherian_of_linearEquiv R (M a × ((i : s) → M i)) _ _ _ _ _ _ ?_ <|
      @isNoetherian_prod R (M a) _ _ _ _ _ _ _ ih
  refine
  { toFun := fun f i =>
      (Finset.mem_insert.1 i.2).by_cases
        (fun h : i.1 = a => show M i.1 from Eq.recOn h.symm f.1)
        (fun h : i.1 ∈ s => show M i.1 from f.2 ⟨i.1, h⟩),
    invFun := fun f =>
      (f ⟨a, Finset.mem_insert_self _ _⟩, fun i => f ⟨i.1, Finset.mem_insert_of_mem i.2⟩),
    map_add' := ?_,
    map_smul' := ?_
    left_inv := ?_,
    right_inv := ?_ }
  · intro f g
    ext i
    unfold Or.by_cases
    cases' i with i hi
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · change _ = _ + _
      simp only [dif_pos]
      rfl
    · change _ = _ + _
      have : ¬i = a := by
        rintro rfl
        exact has h
      simp only [dif_neg this, dif_pos h]
      rfl
  · intro c f
    ext i
    unfold Or.by_cases
    cases' i with i hi
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · dsimp
      simp only [dif_pos]
    · dsimp
      have : ¬i = a := by
        rintro rfl
        exact has h
      simp only [dif_neg this, dif_pos h]
  · intro f
    apply Prod.ext
    · simp only [Or.by_cases, dif_pos]
    · ext ⟨i, his⟩
      have : ¬i = a := by
        rintro rfl
        exact has his
      simp only [Or.by_cases, this, not_false_iff, dif_neg]
  · intro f
    ext ⟨i, hi⟩
    rcases Finset.mem_insert.1 hi with (rfl | h)
    · simp only [Or.by_cases, dif_pos]
    · have : ¬i = a := by
        rintro rfl
        

Proof state:
R✝ : Type u_1
M✝ : Type u_2
P : Type u_3
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : AddCommGroup P
inst✝⁶ : Module R✝ M✝
inst✝⁵ : Module R✝ P
R : Type u_4
ι : Type u_5
M : ι → Type u_6
inst✝⁴ : Ring R
inst✝³ : (i : ι) → AddCommGroup (M i)
inst✝² : (i : ι) → Module R (M i)
inst✝¹ : Finite ι
inst✝ : ∀ (i : ι), IsNoetherian R (M i)
val✝ : Fintype ι
this : DecidableEq ι
s : Finset ι
ih : IsNoetherian R ((i : { x // x ∈ s }) → M ↑i)
i : ι
h : i ∈ s
has : i ∉ s
f : (i_1 : { x // x ∈ insert i s }) → M ↑i_1
hi : i ∈ insert i s
⊢ False

Next tactic:
exact has h
instance isNoetherian_linearMap : IsNoetherian R (N →ₗ[R] M) := by
  

Proof state:
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : AddCommGroup M
inst✝⁴ : AddCommGroup N
inst✝³ : Module R M
inst✝² : Module R N
inst✝¹ : IsNoetherian R M
inst✝ : Module.Finite R N
⊢ IsNoetherian R (N →ₗ[R] M)

Next tactic:
obtain ⟨n, f, hf⟩ := Module.Finite.exists_fin' R N
instance isNoetherian_linearMap : IsNoetherian R (N →ₗ[R] M) := by
  obtain ⟨n, f, hf⟩ := Module.Finite.exists_fin' R N
  

Proof state:
case intro.intro
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : AddCommGroup M
inst✝⁴ : AddCommGroup N
inst✝³ : Module R M
inst✝² : Module R N
inst✝¹ : IsNoetherian R M
inst✝ : Module.Finite R N
n : ℕ
f : (Fin n → R) →ₗ[R] N
hf : Function.Surjective ⇑f
⊢ IsNoetherian R (N →ₗ[R] M)

Next tactic:
let g : (N →ₗ[R] M) →ₗ[R] (Fin n → R) →ₗ[R] M := (LinearMap.llcomp R (Fin n → R) N M).flip f
instance isNoetherian_linearMap : IsNoetherian R (N →ₗ[R] M) := by
  obtain ⟨n, f, hf⟩ := Module.Finite.exists_fin' R N
  let g : (N →ₗ[R] M) →ₗ[R] (Fin n → R) →ₗ[R] M := (LinearMap.llcomp R (Fin n → R) N M).flip f
  

Proof state:
case intro.intro
R : Type u_1
M : Type u_2
N : Type u_3
inst✝⁶ : CommRing R
inst✝⁵ : AddCommGroup M
inst✝⁴ : AddCommGroup N
inst✝³ : Module R M
inst✝² : Module R N
inst✝¹ : IsNoetherian R M
inst✝ : Module.Finite R N
n : ℕ
f : (Fin n → R) →ₗ[R] N
hf : Function.Surjective ⇑f
g : (N →ₗ[R] M) →ₗ[R] (Fin n → R) →ₗ[R] M := (LinearMap.flip (LinearMap.llcomp R (Fin n → R) N M)) f
⊢ IsNoetherian R (N →ₗ[R] M)

Next tactic:
exact isNoetherian_of_injective g hf.injective_linearMapComp_right
theorem isNoetherian_iff_wellFounded :
    IsNoetherian R M ↔ WellFounded ((· > ·) : Submodule R M → Submodule R M → Prop) := by
  

Proof state:
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
⊢ IsNoetherian R M ↔ WellFounded fun x x_1 => x > x_1

Next tactic:
have := (CompleteLattice.wellFounded_characterisations <| Submodule R M).out 0 3
theorem isNoetherian_iff_wellFounded :
    IsNoetherian R M ↔ WellFounded ((· > ·) : Submodule R M → Submodule R M → Prop) := by
  have := (CompleteLattice.wellFounded_characterisations <| Submodule R M).out 0 3
  -- Porting note: inlining this makes rw complain about it being a metavariable
  

Proof state:
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
this : (WellFounded fun x x_1 => x > x_1) ↔ ∀ (k : Submodule R M), CompleteLattice.IsCompactElement k
⊢ IsNoetherian R M ↔ WellFounded fun x x_1 => x > x_1

Next tactic:
rw [this]
theorem isNoetherian_iff_wellFounded :
    IsNoetherian R M ↔ WellFounded ((· > ·) : Submodule R M → Submodule R M → Prop) := by
  have := (CompleteLattice.wellFounded_characterisations <| Submodule R M).out 0 3
  -- Porting note: inlining this makes rw complain about it being a metavariable
  rw [this]
  

Proof state:
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
this : (WellFounded fun x x_1 => x > x_1) ↔ ∀ (k : Submodule R M), CompleteLattice.IsCompactElement k
⊢ IsNoetherian R M ↔ ∀ (k : Submodule R M), CompleteLattice.IsCompactElement k

Next tactic:
exact
    ⟨fun ⟨h⟩ => fun k => (fg_iff_compact k).mp (h k), fun h =>
      ⟨fun k => (fg_iff_compact k).mpr (h k)⟩⟩
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  

Proof state:
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
⊢ IsNoetherian R M ↔ WellFounded fun x x_1 => x > x_1

Next tactic:
let α := { N : Submodule R M // N.FG }
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  

Proof state:
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
⊢ IsNoetherian R M ↔ WellFounded fun x x_1 => x > x_1

Next tactic:
constructor
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · 

Proof state:
case mp
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
⊢ IsNoetherian R M → WellFounded fun x x_1 => x > x_1

Next tactic:
intro H
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    

Proof state:
case mp
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
H : IsNoetherian R M
⊢ WellFounded fun x x_1 => x > x_1

Next tactic:
let f : α ↪o Submodule R M := OrderEmbedding.subtype _
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    let f : α ↪o Submodule R M := OrderEmbedding.subtype _
    

Proof state:
case mp
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
H : IsNoetherian R M
f : α ↪o Submodule R M := OrderEmbedding.subtype fun N => FG N
⊢ WellFounded fun x x_1 => x > x_1

Next tactic:
exact OrderEmbedding.wellFounded f.dual (isNoetherian_iff_wellFounded.mp H)
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    let f : α ↪o Submodule R M := OrderEmbedding.subtype _
    exact OrderEmbedding.wellFounded f.dual (isNoetherian_iff_wellFounded.mp H)
  · 

Proof state:
case mpr
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
⊢ (WellFounded fun x x_1 => x > x_1) → IsNoetherian R M

Next tactic:
intro H
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    let f : α ↪o Submodule R M := OrderEmbedding.subtype _
    exact OrderEmbedding.wellFounded f.dual (isNoetherian_iff_wellFounded.mp H)
  · intro H
    

Proof state:
case mpr
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
H : WellFounded fun x x_1 => x > x_1
⊢ IsNoetherian R M

Next tactic:
constructor
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    let f : α ↪o Submodule R M := OrderEmbedding.subtype _
    exact OrderEmbedding.wellFounded f.dual (isNoetherian_iff_wellFounded.mp H)
  · intro H
    constructor
    

Proof state:
case mpr.noetherian
R : Type u_1
M : Type u_2
P : Type u_3
N : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
H : WellFounded fun x x_1 => x > x_1
⊢ ∀ (s : Submodule R M), FG s

Next tactic:
intro N
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    let f : α ↪o Submodule R M := OrderEmbedding.subtype _
    exact OrderEmbedding.wellFounded f.dual (isNoetherian_iff_wellFounded.mp H)
  · intro H
    constructor
    intro N
    

Proof state:
case mpr.noetherian
R : Type u_1
M : Type u_2
P : Type u_3
N✝ : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N✝
inst✝² : Module R N✝
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
H : WellFounded fun x x_1 => x > x_1
N : Submodule R M
⊢ FG N

Next tactic:
obtain ⟨⟨N₀, h₁⟩, e : N₀ ≤ N, h₂⟩ :=
      WellFounded.has_min H { N' : α | N'.1 ≤ N } ⟨⟨⊥, Submodule.fg_bot⟩, @bot_le _ _ _ N⟩
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    let f : α ↪o Submodule R M := OrderEmbedding.subtype _
    exact OrderEmbedding.wellFounded f.dual (isNoetherian_iff_wellFounded.mp H)
  · intro H
    constructor
    intro N
    obtain ⟨⟨N₀, h₁⟩, e : N₀ ≤ N, h₂⟩ :=
      WellFounded.has_min H { N' : α | N'.1 ≤ N } ⟨⟨⊥, Submodule.fg_bot⟩, @bot_le _ _ _ N⟩
    

Proof state:
case mpr.noetherian.intro.mk.intro
R : Type u_1
M : Type u_2
P : Type u_3
N✝ : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N✝
inst✝² : Module R N✝
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
H : WellFounded fun x x_1 => x > x_1
N N₀ : Submodule R M
h₁ : FG N₀
e : N₀ ≤ N
h₂ : ∀ x ∈ {N' | ↑N' ≤ N}, ¬x > { val := N₀, property := h₁ }
⊢ FG N

Next tactic:
convert h₁
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    let f : α ↪o Submodule R M := OrderEmbedding.subtype _
    exact OrderEmbedding.wellFounded f.dual (isNoetherian_iff_wellFounded.mp H)
  · intro H
    constructor
    intro N
    obtain ⟨⟨N₀, h₁⟩, e : N₀ ≤ N, h₂⟩ :=
      WellFounded.has_min H { N' : α | N'.1 ≤ N } ⟨⟨⊥, Submodule.fg_bot⟩, @bot_le _ _ _ N⟩
    convert h₁
    

Proof state:
case h.e'_6
R : Type u_1
M : Type u_2
P : Type u_3
N✝ : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N✝
inst✝² : Module R N✝
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
H : WellFounded fun x x_1 => x > x_1
N N₀ : Submodule R M
h₁ : FG N₀
e : N₀ ≤ N
h₂ : ∀ x ∈ {N' | ↑N' ≤ N}, ¬x > { val := N₀, property := h₁ }
⊢ N = N₀

Next tactic:
refine' (e.antisymm _).symm
theorem isNoetherian_iff_fg_wellFounded :
    IsNoetherian R M ↔
      WellFounded
        ((· > ·) : { N : Submodule R M // N.FG } → { N : Submodule R M // N.FG } → Prop) := by
  let α := { N : Submodule R M // N.FG }
  constructor
  · intro H
    let f : α ↪o Submodule R M := OrderEmbedding.subtype _
    exact OrderEmbedding.wellFounded f.dual (isNoetherian_iff_wellFounded.mp H)
  · intro H
    constructor
    intro N
    obtain ⟨⟨N₀, h₁⟩, e : N₀ ≤ N, h₂⟩ :=
      WellFounded.has_min H { N' : α | N'.1 ≤ N } ⟨⟨⊥, Submodule.fg_bot⟩, @bot_le _ _ _ N⟩
    convert h₁
    refine' (e.antisymm _).symm
    

Proof state:
case h.e'_6
R : Type u_1
M : Type u_2
P : Type u_3
N✝ : Type w
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N✝
inst✝² : Module R N✝
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_2 := { N // FG N }
H : WellFounded fun x x_1 => x > x_1
N N₀ : Submodule R M
h₁ : FG N₀
e : N₀ ≤ N
h₂ : ∀ x ∈ {N' | ↑N' ≤ N}, ¬x > { val := N₀, property := h₁ }
⊢ N ≤ N₀

Next tactic:
by_contra h₃