/-- A finitely generated torsion module over a PID is isomorphic to a direct sum of some
  `R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTorsion R N) :
    ∃ (ι : Type u) (_ : Fintype ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i) (e : ι → ℕ),
      Nonempty <| N ≃ₗ[R] ⨁ i : ι, R ⧸ R ∙ p i ^ e i := by
  obtain ⟨I, fI, _, p, hp, e, h⟩ := Submodule.exists_isInternal_prime_power_torsion_of_pid hN
  haveI := fI
  have :
    ∀ i,
      ∃ (d : ℕ) (k : Fin d → ℕ),
        Nonempty <| torsionBy R N (p i ^ e i) ≃ₗ[R] ⨁ j, R ⧸ R ∙ p i ^ k j := by
    haveI := fun i => isNoetherian_submodule' (torsionBy R N <| p i ^ e i)
    exact fun i =>
      torsion_by_prime_power_decomposition.{u, v} (hp i)
        ((isTorsion'_powers_iff <| p i).mpr fun x => ⟨e i, smul_torsionBy _ _⟩)
  classical
  refine'
    ⟨Σ i, Fin (this i).choose, inferInstance, fun ⟨i, _⟩ => p i, fun ⟨i, _⟩ => hp i, fun ⟨i, j⟩ =>
      (this i).choose_spec.choose j,
      ⟨(LinearEquiv.ofBijective (DirectSum.coeLinearMap _) h).symm.trans <|
          (DFinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
            (DirectSum.sigmaLcurryEquiv R).symm.trans
              (DFinsupp.mapRange.linearEquiv fun i => quotEquivOfEq _ _ _)⟩⟩
  cases' i with i j
  

Proof state:
case intro.intro.intro.intro.intro.intro.mk
R : Type u
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type v
inst✝³ : AddCommGroup M
inst✝² : Module R M
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
h' : Finite R N
hN : IsTorsion R N
I : Type u
fI : Fintype I
w✝ : DecidableEq I
p : I → R
hp : ∀ (i : I), Irreducible (p i)
e : I → ℕ
h : DirectSum.IsInternal fun i => torsionBy R N (p i ^ e i)
this✝ : Fintype I
this : ∀ (i : I), ∃ d k, Nonempty (↥(torsionBy R N (p i ^ e i)) ≃ₗ[R] ⨁ (j : Fin d), R ⧸ span R {p i ^ k j})
i : I
j : Fin (Exists.choose (_ : ∃ d k, Nonempty (↥(torsionBy R N (p i ^ e i)) ≃ₗ[R] ⨁ (j : Fin d), R ⧸ span R {p i ^ k j})))
⊢ span R
      {p { fst := i, snd := j }.fst ^
          Exists.choose
            (_ :
              ∃ k,
                Nonempty
                  (↥(torsionBy R N (p { fst := i, snd := j }.fst ^ e { fst := i, snd := j }.fst)) ≃ₗ[R]
                    ⨁ (j_1 :
                      Fin
                        (Exists.choose
                          (_ :
                            ∃ d k,
                              Nonempty
                                (↥(torsionBy R N (p { fst := i, snd := j }.fst ^ e { fst := i, snd := j }.fst)) ≃ₗ[R]
                                  ⨁ (j_1 : Fin d), R ⧸ span R {p { fst := i, snd := j }.fst ^ k j_1})))),
                      R ⧸ span R {p { fst := i, snd := j }.fst ^ k j_1}))
            { fst := i, snd := j }.snd} =
    span R
      {(fun x =>
              match x with
              | { fst := i, snd := snd } => p i)
            { fst := i, snd := j } ^
          (fun x =>
              match x with
              | { fst := i, snd := j } =>
                Exists.choose
                  (_ :
                    ∃ k,
                      Nonempty
                        (↥(torsionBy R N (p i ^ e i)) ≃ₗ[R]
                          ⨁ (j :
                            Fin
                              (Exists.choose
                                (_ :
                                  ∃ d k,
                                    Nonempty
                                      (↥(torsionBy R N (p i ^ e i)) ≃ₗ[R] ⨁ (j : Fin d), R ⧸ span R {p i ^ k j})))),
                            R ⧸ span R {p i ^ k j}))
                  j)
            { fst := i, snd := j }}

Next tactic:
simp only