-- Mathlib/RingTheory/Artinian/Module.lean
theorem eventually_codisjoint_ker_pow_range_pow (f : M →ₗ[R] M) :
    ∀ᶠ n in atTop, Codisjoint (LinearMap.ker (f ^ n)) (LinearMap.range (f ^ n))

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
⊢ ker (f ^ m) ⊔ range (f ^ m) = ⊤

Tactic:
simp_rw [← hn _ hm, Submodule.eq_top_iff', Submodule.mem_sup]

Result:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
⊢ ∀ (x : M), ∃ y ∈ ker (f ^ m), ∃ z ∈ range (f ^ n), y + z = x

Proof state:
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 : ℕ) in atTop, Codisjoint (ker (f ^ n)) (range (f ^ n))

Tactic:
obtain ⟨n, hn : ∀ m, n ≤ m → LinearMap.range (f ^ n) = LinearMap.range (f ^ m)⟩ :=
  IsArtinian.monotone_stabilizes f.iterateRange

Result:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
⊢ ∀ᶠ (n : ℕ) in atTop, Codisjoint (ker (f ^ n)) (range (f ^ n))

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x : M
⊢ ∃ y ∈ ker (f ^ m), ∃ z ∈ range (f ^ n), y + z = x

Tactic:
rsuffices ⟨y, hy⟩ : ∃ y, (f ^ m) ((f ^ n) y) = (f ^ m) x

Result:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x y : M
hy : (f ^ m) ((f ^ n) y) = (f ^ m) x
⊢ ∃ y ∈ ker (f ^ m), ∃ z ∈ range (f ^ n), y + z = x

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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x : M
⊢ ∃ y, (f ^ m) ((f ^ n) y) = (f ^ m) x

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x y : M
hy : (f ^ m) ((f ^ n) y) = (f ^ m) x
⊢ ∃ y ∈ ker (f ^ m), ∃ z ∈ range (f ^ n), y + z = x

Tactic:
exact ⟨x - (f ^ n) y, by simp [hy], (f ^ n) y, by simp⟩

Result:
no goals

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x : M
⊢ (f ^ m) x ∈ range (f ^ m)

Tactic:
exact LinearMap.mem_range_self (f ^ m) x

Result:
no goals

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x y : M
hy : (f ^ m) ((f ^ n) y) = (f ^ m) x
⊢ x - (f ^ n) y ∈ ker (f ^ m)

Tactic:
simp [hy]

Result:
no goals

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x : M
⊢ ∃ y, (f ^ m) ((f ^ n) y) = (f ^ m) x

Tactic:
simp_rw [f.pow_apply n, f.pow_apply m, ← iterate_add_apply, ← f.pow_apply (m + n),
  ← f.pow_apply m, ← mem_range (f := _), ← hn _ (n.le_add_left m), hn _ hm]

Result:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x : M
⊢ (f ^ m) x ∈ range (f ^ m)

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
⊢ ∀ (x : M), ∃ y ∈ ker (f ^ m), ∃ z ∈ range (f ^ n), y + z = x

Tactic:
intro x

Result:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x : M
⊢ ∃ y ∈ ker (f ^ m), ∃ z ∈ range (f ^ n), y + z = x

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
x y : M
hy : (f ^ m) ((f ^ n) y) = (f ^ m) x
⊢ (f ^ n) y ∈ range (f ^ n) ∧ x - (f ^ n) y + (f ^ n) y = x

Tactic:
simp

Result:
no goals

Proof state:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
⊢ ∀ᶠ (n : ℕ) in atTop, Codisjoint (ker (f ^ n)) (range (f ^ n))

Tactic:
refine eventually_atTop.mpr ⟨n, fun m hm ↦ codisjoint_iff.mpr ?_⟩

Result:
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 : ℕ
hn : ∀ (m : ℕ), n ≤ m → range (f ^ n) = range (f ^ m)
m : ℕ
hm : m ≥ n
⊢ ker (f ^ m) ⊔ range (f ^ m) = ⊤