/-- An isomorphism of `R`-modules `R^n ≃ R^m` induces an isomorphism of `R/I`-modules
    `R^n/I^n ≃ R^m/I^m`. -/
private def induced_equiv [Fintype ι'] (I : Ideal R) (e : (ι → R) ≃ₗ[R] ι' → R) :
    ((ι → R) ⧸ I.pi ι) ≃ₗ[R ⧸ I] (ι' → R) ⧸ I.pi ι' := by
  refine'
    { toFun := induced_map I e
      invFun := induced_map I e.symm.. }
  all_goals
    first |rintro ⟨a⟩ ⟨b⟩|rintro ⟨a⟩
  -- porting note: the next 4 lines were necessary because Lean couldn't correctly infer `(I.pi ι)`
  -- and `(I.pi ι')` on its own.
  pick_goal 3
  convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
  

Proof state:
case refine'_3.mk.convert_3
R : Type u
inst✝² : CommRing R
I✝ : Ideal R
ι : Type v
inst✝¹ : Fintype ι
ι' : Type w
inst✝ : Fintype ι'
I : Ideal R
e : (ι → R) ≃ₗ[R] ι' → R
x✝ : (ι → R) ⧸ Ideal.pi I ι
a : ι → R
⊢ (Ideal.Quotient.mk (Ideal.pi I ι)) (↑(LinearEquiv.symm e) (↑e a)) = (Ideal.Quotient.mk (Ideal.pi I ι)) a
case refine'_1.mk.mk
R : Type u
inst✝² : CommRing R
I✝ : Ideal R
ι : Type v
inst✝¹ : Fintype ι
ι' : Type w
inst✝ : Fintype ι'
I : Ideal R
e : (ι → R) ≃ₗ[R] ι' → R
x✝ : (ι → R) ⧸ Ideal.pi I ι
a : ι → R
y✝ : (ι → R) ⧸ Ideal.pi I ι
b : ι → R
⊢ induced_map I (↑e) (Quot.mk Setoid.r a + Quot.mk Setoid.r b) =
    induced_map I (↑e) (Quot.mk Setoid.r a) + induced_map I (↑e) (Quot.mk Setoid.r b)
case refine'_2.mk.mk
R : Type u
inst✝² : CommRing R
I✝ : Ideal R
ι : Type v
inst✝¹ : Fintype ι
ι' : Type w
inst✝ : Fintype ι'
I : Ideal R
e : (ι → R) ≃ₗ[R] ι' → R
r✝ : R ⧸ I
a : R
x✝ : (ι → R) ⧸ Ideal.pi I ι
b : ι → R
⊢ AddHom.toFun
      { toFun := induced_map I ↑e,
        map_add' :=
          (_ :
            ∀ (x y : (ι → R) ⧸ Ideal.pi I ι),
              induced_map I (↑e) (x + y) = induced_map I (↑e) x + induced_map I (↑e) y) }
      (Quot.mk Setoid.r a • Quot.mk Setoid.r b) =
    (RingHom.id (R ⧸ I)) (Quot.mk Setoid.r a) •
      AddHom.toFun
        { toFun := induced_map I ↑e,
          map_add' :=
            (_ :
              ∀ (x y : (ι → R) ⧸ Ideal.pi I ι),
                induced_map I (↑e) (x + y) = induced_map I (↑e) x + induced_map I (↑e) y) }
        (Quot.mk Setoid.r b)
case refine'_4.mk
R : Type u
inst✝² : CommRing R
I✝ : Ideal R
ι : Type v
inst✝¹ : Fintype ι
ι' : Type w
inst✝ : Fintype ι'
I : Ideal R
e : (ι → R) ≃ₗ[R] ι' → R
x✝ : (ι' → R) ⧸ Ideal.pi I ι'
a : ι' → R
⊢ AddHom.toFun
      {
          toAddHom :=
            { toFun := induced_map I ↑e,
              map_add' :=
                (_ :
                  ∀ (x y : (ι → R) ⧸ Ideal.pi I ι),
                    induced_map I (↑e) (x + y) = induced_map I (↑e) x + induced_map I (↑e) y) },
          map_smul' :=
            (_ :
              ∀ (r : R ⧸ I) (x : (ι → R) ⧸ Ideal.pi I ι),
                AddHom.toFun
                    { toFun := induced_map I ↑e,
                      map_add' :=
                        (_ :
                          ∀ (x y : (ι → R) ⧸ Ideal.pi I ι),
                            induced_map I (↑e) (x + y) = induced_map I (↑e) x + induced_map I (↑e) y) }
                    (r • x) =
                  (RingHom.id (R ⧸ I)) r •
                    AddHom.toFun
                      { toFun := induced_map I ↑e,
                        map_add' :=
                          (_ :
                            ∀ (x y : (ι → R) ⧸ Ideal.pi I ι),
                              induced_map I (↑e) (x + y) = induced_map I (↑e) x + induced_map I (↑e) y) }
                      x) }.toAddHom
      (induced_map I (↑(LinearEquiv.symm e)) (Quot.mk Setoid.r a)) =
    Quot.mk Setoid.r a

Next tactic:
congr