-- Mathlib/Algebra/Module/PID.lean
theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoid.powers p))
    [h' : Module.Finite R N] :
    ∃ (d : ℕ) (k : Fin d → ℕ), Nonempty <| N ≃ₗ[R] ⨁ i : Fin d, R ⧸ R ∙ p ^ (k i : ℕ)

Proof state:
case h.succ.intro.refine_3.intro.intro.refine_2.refine_2
R : Type u
inst✝⁴ : CommRing R
inst✝³ : IsPrincipalIdealRing R
inst✝² : IsDomain R
p : R
hp : Irreducible p
d : ℕ
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
hN : IsTorsion' N ↥(Submonoid.powers p)
s : Fin (d + 1) → N
hs : Submodule.span R (Set.range s) = ⊤
this✝ : (x : N) → Decidable (x = 0)
j : Fin d.succ
hj : IsTorsionBy R N (p ^ pOrder hN (s j))
s' : Fin d → N ⧸ Submodule.span R {s j} := Submodule.Quotient.mk ∘ s ∘ j.succAbove
k : Fin d → ℕ
f : (N ⧸ Submodule.span R {s j}) ≃ₗ[R] ⨁ (i : Fin d), R ⧸ Submodule.span R {p ^ k i}
this :
  ∀ (i : Fin d),
    ∃ x,
      p ^ k i • x = 0 ∧
        f (Submodule.Quotient.mk x) = (DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) 1
⊢ (↑(f ≪≫ₗ ULift.moduleEquiv.symm) ∘ₗ (Submodule.span R {s j}).mkQ) ∘ₗ
      (DirectSum.toModule R (Fin d) N fun i =>
          liftQSpanSingleton (p ^ k i) (LinearMap.toSpanSingleton R N ⋯.choose) ⋯) ∘ₗ
        ↑ULift.moduleEquiv =
    LinearMap.id

Tactic:
rw [← f.comp_coe, LinearMap.comp_assoc, LinearMap.comp_assoc,
  LinearEquiv.toLinearMap_symm_comp_eq, LinearMap.comp_id, ← LinearMap.comp_assoc,
  ← LinearMap.comp_assoc]

Result:
case h.succ.intro.refine_3.intro.intro.refine_2.refine_2
R : Type u
inst✝⁴ : CommRing R
inst✝³ : IsPrincipalIdealRing R
inst✝² : IsDomain R
p : R
hp : Irreducible p
d : ℕ
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
hN : IsTorsion' N ↥(Submonoid.powers p)
s : Fin (d + 1) → N
hs : Submodule.span R (Set.range s) = ⊤
this✝ : (x : N) → Decidable (x = 0)
j : Fin d.succ
hj : IsTorsionBy R N (p ^ pOrder hN (s j))
s' : Fin d → N ⧸ Submodule.span R {s j} := Submodule.Quotient.mk ∘ s ∘ j.succAbove
k : Fin d → ℕ
f : (N ⧸ Submodule.span R {s j}) ≃ₗ[R] ⨁ (i : Fin d), R ⧸ Submodule.span R {p ^ k i}
this :
  ∀ (i : Fin d),
    ∃ x,
      p ^ k i • x = 0 ∧
        f (Submodule.Quotient.mk x) = (DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) 1
⊢ ((↑f ∘ₗ (Submodule.span R {s j}).mkQ) ∘ₗ
        DirectSum.toModule R (Fin d) N fun i =>
          liftQSpanSingleton (p ^ k i) (LinearMap.toSpanSingleton R N ⋯.choose) ⋯) ∘ₗ
      ↑ULift.moduleEquiv =
    ↑ULift.moduleEquiv

Proof state:
R : Type u
inst✝⁴ : CommRing R
inst✝³ : IsPrincipalIdealRing R
inst✝² : IsDomain R
p : R
hp : Irreducible p
d : ℕ
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
hN : IsTorsion' N ↥(Submonoid.powers p)
s : Fin (d + 1) → N
hs : Submodule.span R (Set.range s) = ⊤
this : (x : N) → Decidable (x = 0)
j : Fin d.succ
hj : IsTorsionBy R N (p ^ pOrder hN (s j))
s' : Fin d → N ⧸ Submodule.span R {s j} := Submodule.Quotient.mk ∘ s ∘ j.succAbove
k : Fin d → ℕ
f : (N ⧸ Submodule.span R {s j}) ≃ₗ[R] ⨁ (i : Fin d), R ⧸ Submodule.span R {p ^ k i}
i : Fin d
fi : R ⧸ Submodule.span R {p ^ k i} →ₗ[R] N ⧸ Submodule.span R {s j} :=
  ↑f.symm ∘ₗ DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i
⊢ ∃ x,
    p ^ k i • x = 0 ∧
      f (Submodule.Quotient.mk x) = (DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) 1

Tactic:
obtain ⟨x, h0, h1⟩ := exists_smul_eq_zero_and_mk_eq hp hN hj fi

Result:
case intro.intro
R : Type u
inst✝⁴ : CommRing R
inst✝³ : IsPrincipalIdealRing R
inst✝² : IsDomain R
p : R
hp : Irreducible p
d : ℕ
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
hN : IsTorsion' N ↥(Submonoid.powers p)
s : Fin (d + 1) → N
hs : Submodule.span R (Set.range s) = ⊤
this : (x : N) → Decidable (x = 0)
j : Fin d.succ
hj : IsTorsionBy R N (p ^ pOrder hN (s j))
s' : Fin d → N ⧸ Submodule.span R {s j} := Submodule.Quotient.mk ∘ s ∘ j.succAbove
k : Fin d → ℕ
f : (N ⧸ Submodule.span R {s j}) ≃ₗ[R] ⨁ (i : Fin d), R ⧸ Submodule.span R {p ^ k i}
i : Fin d
fi : R ⧸ Submodule.span R {p ^ k i} →ₗ[R] N ⧸ Submodule.span R {s j} :=
  ↑f.symm ∘ₗ DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i
x : N
h0 : p ^ k i • x = 0
h1 : Submodule.Quotient.mk x = fi 1
⊢ ∃ x,
    p ^ k i • x = 0 ∧
      f (Submodule.Quotient.mk x) = (DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) 1

Proof state:
case h.succ.intro.refine_3.intro.intro.refine_2.refine_2.H.h.h
R : Type u
inst✝⁴ : CommRing R
inst✝³ : IsPrincipalIdealRing R
inst✝² : IsDomain R
p : R
hp : Irreducible p
d : ℕ
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
hN : IsTorsion' N ↥(Submonoid.powers p)
s : Fin (d + 1) → N
hs : Submodule.span R (Set.range s) = ⊤
this✝ : (x : N) → Decidable (x = 0)
j : Fin d.succ
hj : IsTorsionBy R N (p ^ pOrder hN (s j))
s' : Fin d → N ⧸ Submodule.span R {s j} := Submodule.Quotient.mk ∘ s ∘ j.succAbove
k : Fin d → ℕ
f : (N ⧸ Submodule.span R {s j}) ≃ₗ[R] ⨁ (i : Fin d), R ⧸ Submodule.span R {p ^ k i}
this :
  ∀ (i : Fin d),
    ∃ x,
      p ^ k i • x = 0 ∧
        f (Submodule.Quotient.mk x) = (DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) 1
i : Fin d
⊢ ((((↑f ∘ₗ (Submodule.span R {s j}).mkQ) ∘ₗ
            DirectSum.toModule R (Fin d) N fun i =>
              liftQSpanSingleton (p ^ k i) (LinearMap.toSpanSingleton R N ⋯.choose) ⋯) ∘ₗ
          DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) ∘ₗ
        (Submodule.span R {p ^ k i}).mkQ)
      1 =
    ((LinearMap.id ∘ₗ DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) ∘ₗ
        (Submodule.span R {p ^ k i}).mkQ)
      1

Tactic:
simp only [LinearMap.coe_comp, Function.comp_apply, mkQ_apply]

Result:
case h.succ.intro.refine_3.intro.intro.refine_2.refine_2.H.h.h
R : Type u
inst✝⁴ : CommRing R
inst✝³ : IsPrincipalIdealRing R
inst✝² : IsDomain R
p : R
hp : Irreducible p
d : ℕ
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
hN : IsTorsion' N ↥(Submonoid.powers p)
s : Fin (d + 1) → N
hs : Submodule.span R (Set.range s) = ⊤
this✝ : (x : N) → Decidable (x = 0)
j : Fin d.succ
hj : IsTorsionBy R N (p ^ pOrder hN (s j))
s' : Fin d → N ⧸ Submodule.span R {s j} := Submodule.Quotient.mk ∘ s ∘ j.succAbove
k : Fin d → ℕ
f : (N ⧸ Submodule.span R {s j}) ≃ₗ[R] ⨁ (i : Fin d), R ⧸ Submodule.span R {p ^ k i}
this :
  ∀ (i : Fin d),
    ∃ x,
      p ^ k i • x = 0 ∧
        f (Submodule.Quotient.mk x) = (DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) 1
i : Fin d
⊢ ↑f
      (Submodule.Quotient.mk
        ((DirectSum.toModule R (Fin d) N fun i =>
            liftQSpanSingleton (p ^ k i) (LinearMap.toSpanSingleton R N ⋯.choose) ⋯)
          ((DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) (Submodule.Quotient.mk 1)))) =
    LinearMap.id ((DirectSum.lof R (Fin d) (fun i => R ⧸ Submodule.span R {p ^ k i}) i) (Submodule.Quotient.mk 1))