Theorem: IsArtinian.exists_endomorphism_iterate_ker_sup_range_eq_top
File: Mathlib/RingTheory/Artinian.lean

tactic: obtain ⟨n, w⟩ :=
  monotone_stabilizes (f.iterateRange.comp ⟨fun n => n + 1, fun n m w => by linarith⟩)
state_before: R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
⊢ ∃ n, n ≠ 0 ∧ LinearMap.ker (f ^ n) ⊔ LinearMap.range (f ^ n) = ⊤

tactic: specialize w (n + 1 + n) (by linarith)
state_before: case intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w :
  ∀ (m : ℕ),
    n ≤ m →
      ↑(OrderHom.comp (LinearMap.iterateRange f)
              { toFun := fun n => n + 1,
                monotone' := (_ : ∀ (n m : ℕ), n ≤ m → (fun n => n + 1) n ≤ (fun n => n + 1) m) })
          n =
        ↑(OrderHom.comp (LinearMap.iterateRange f)
              { toFun := fun n => n + 1,
                monotone' := (_ : ∀ (n m : ℕ), n ≤ m → (fun n => n + 1) n ≤ (fun n => n + 1) m) })
          m
⊢ ∃ n, n ≠ 0 ∧ LinearMap.ker (f ^ n) ⊔ LinearMap.range (f ^ n) = ⊤

tactic: dsimp at w
state_before: case intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w :
  ↑(OrderHom.comp (LinearMap.iterateRange f)
          { toFun := fun n => n + 1, monotone' := (_ : ∀ (n m : ℕ), n ≤ m → (fun n => n + 1) n ≤ (fun n => n + 1) m) })
      n =
    ↑(OrderHom.comp (LinearMap.iterateRange f)
          { toFun := fun n => n + 1, monotone' := (_ : ∀ (n m : ℕ), n ≤ m → (fun n => n + 1) n ≤ (fun n => n + 1) m) })
      (n + 1 + n)
⊢ ∃ n, n ≠ 0 ∧ LinearMap.ker (f ^ n) ⊔ LinearMap.range (f ^ n) = ⊤

tactic: refine' ⟨n + 1, Nat.succ_ne_zero _, _⟩
state_before: case intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
⊢ ∃ n, n ≠ 0 ∧ LinearMap.ker (f ^ n) ⊔ LinearMap.range (f ^ n) = ⊤

tactic: simp_rw [eq_top_iff', mem_sup]
state_before: case intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
⊢ LinearMap.ker (f ^ (n + 1)) ⊔ LinearMap.range (f ^ (n + 1)) = ⊤

tactic: intro x
state_before: case intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
⊢ ∀ (x : M), ∃ y, y ∈ LinearMap.ker (f ^ (n + 1)) ∧ ∃ z, z ∈ LinearMap.range (f ^ (n + 1)) ∧ y + z = x

tactic: have : (f ^ (n + 1)) x ∈ LinearMap.range (f ^ (n + 1 + n + 1)) := by
  rw [← w]
  exact mem_range_self _
state_before: case intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x : M
⊢ ∃ y, y ∈ LinearMap.ker (f ^ (n + 1)) ∧ ∃ z, z ∈ LinearMap.range (f ^ (n + 1)) ∧ y + z = x

tactic: rcases this with ⟨y, hy⟩
state_before: case intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x : M
this : ↑(f ^ (n + 1)) x ∈ LinearMap.range (f ^ (n + 1 + n + 1))
⊢ ∃ y, y ∈ LinearMap.ker (f ^ (n + 1)) ∧ ∃ z, z ∈ LinearMap.range (f ^ (n + 1)) ∧ y + z = x

tactic: use x - (f ^ (n + 1)) y
state_before: case intro.intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x y : M
hy : ↑(f ^ (n + 1 + n + 1)) y = ↑(f ^ (n + 1)) x
⊢ ∃ y, y ∈ LinearMap.ker (f ^ (n + 1)) ∧ ∃ z, z ∈ LinearMap.range (f ^ (n + 1)) ∧ y + z = x

tactic: constructor
state_before: case intro.intro
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x y : M
hy : ↑(f ^ (n + 1 + n + 1)) y = ↑(f ^ (n + 1)) x
⊢ x - ↑(f ^ (n + 1)) y ∈ LinearMap.ker (f ^ (n + 1)) ∧
    ∃ z, z ∈ LinearMap.range (f ^ (n + 1)) ∧ x - ↑(f ^ (n + 1)) y + z = x

tactic: linarith
state_before: R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n m : ℕ
w : n ≤ m
⊢ (fun n => n + 1) n ≤ (fun n => n + 1) m

tactic: linarith
state_before: R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w :
  ∀ (m : ℕ),
    n ≤ m →
      ↑(OrderHom.comp (LinearMap.iterateRange f)
              { toFun := fun n => n + 1,
                monotone' := (_ : ∀ (n m : ℕ), n ≤ m → (fun n => n + 1) n ≤ (fun n => n + 1) m) })
          n =
        ↑(OrderHom.comp (LinearMap.iterateRange f)
              { toFun := fun n => n + 1,
                monotone' := (_ : ∀ (n m : ℕ), n ≤ m → (fun n => n + 1) n ≤ (fun n => n + 1) m) })
          m
⊢ n ≤ n + 1 + n

tactic: rw [← w]
state_before: R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x : M
⊢ ↑(f ^ (n + 1)) x ∈ LinearMap.range (f ^ (n + 1 + n + 1))

tactic: exact mem_range_self _
state_before: R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x : M
⊢ ↑(f ^ (n + 1)) x ∈ LinearMap.range (f ^ (n + 1))

tactic: rw [LinearMap.mem_ker, LinearMap.map_sub, ← hy, sub_eq_zero, pow_add]
state_before: case intro.intro.left
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x y : M
hy : ↑(f ^ (n + 1 + n + 1)) y = ↑(f ^ (n + 1)) x
⊢ x - ↑(f ^ (n + 1)) y ∈ LinearMap.ker (f ^ (n + 1))

tactic: simp [iterate_add_apply]
state_before: case intro.intro.left
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x y : M
hy : ↑(f ^ (n + 1 + n + 1)) y = ↑(f ^ (n + 1)) x
⊢ ↑(f ^ (n + 1 + n + 1)) y = ↑(f ^ n * f ^ 1) (↑(f ^ n * f ^ 1) y)

tactic: use (f ^ (n + 1)) y
state_before: case intro.intro.right
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x y : M
hy : ↑(f ^ (n + 1 + n + 1)) y = ↑(f ^ (n + 1)) x
⊢ ∃ z, z ∈ LinearMap.range (f ^ (n + 1)) ∧ x - ↑(f ^ (n + 1)) y + z = x

tactic: simp
state_before: case intro.intro.right
R : Type u_1
M : Type u_2
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module R M
inst✝ : IsArtinian R M
f : M →ₗ[R] M
n : ℕ
w : LinearMap.range (f ^ (n + 1)) = LinearMap.range (f ^ (n + 1 + n + 1))
x y : M
hy : ↑(f ^ (n + 1 + n + 1)) y = ↑(f ^ (n + 1)) x
⊢ ↑(f ^ (n + 1)) y ∈ LinearMap.range (f ^ (n + 1)) ∧ x - ↑(f ^ (n + 1)) y + ↑(f ^ (n + 1)) y = x