/-- `R^n/I^n` is isomorphic to `(R/I)^n` as an `R/I`-module. -/
noncomputable def piQuotEquiv : ((ι → R) ⧸ I.pi ι) ≃ₗ[R ⧸ I] ι → (R ⧸ I) where
  toFun := fun x ↦
      Quotient.liftOn' x (fun f i => Ideal.Quotient.mk I (f i)) fun a b hab =>
        funext fun i => (Submodule.Quotient.eq' _).2 (QuotientAddGroup.leftRel_apply.mp hab i)
  map_add' := by rintro ⟨_⟩ ⟨_⟩; rfl
  map_smul' := by rintro ⟨_⟩ ⟨_⟩; 

Proof state:
case mk.mk
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
r✝ : R ⧸ I
a✝¹ : R
x✝ : (ι → R) ⧸ pi I ι
a✝ : ι → R
⊢ AddHom.toFun
      {
        toFun := fun x =>
          Quotient.liftOn' x (fun f i => (Quotient.mk I) (f i))
            (_ :
              ∀ (a b : ι → R),
                Setoid.r a b → (fun f i => (Quotient.mk I) (f i)) a = (fun f i => (Quotient.mk I) (f i)) b),
        map_add' :=
          (_ :
            ∀ (x y : (ι → R) ⧸ pi I ι),
              (fun x =>
                    Quotient.liftOn' x (fun f i => (Quotient.mk I) (f i))
                      (_ :
                        ∀ (a b : ι → R),
                          Setoid.r a b → (fun f i => (Quotient.mk I) (f i)) a = (fun f i => (Quotient.mk I) (f i)) b))
                  (x + y) =
                (fun x =>
                      Quotient.liftOn' x (fun f i => (Quotient.mk I) (f i))
                        (_ :
                          ∀ (a b : ι → R),
                            Setoid.r a b → (fun f i => (Quotient.mk I) (f i)) a = (fun f i => (Quotient.mk I) (f i)) b))
                    x +
                  (fun x =>
                      Quotient.liftOn' x (fun f i => (Quotient.mk I) (f i))
                        (_ :
                          ∀ (a b : ι → R),
                            Setoid.r a b → (fun f i => (Quotient.mk I) (f i)) a = (fun f i => (Quotient.mk I) (f i)) b))
                    y) }
      (Quot.mk Setoid.r a✝¹ • Quot.mk Setoid.r a✝) =
    (RingHom.id (R ⧸ I)) (Quot.mk Setoid.r a✝¹) •
      AddHom.toFun
        {
          toFun := fun x =>
            Quotient.liftOn' x (fun f i => (Quotient.mk I) (f i))
              (_ :
                ∀ (a b : ι → R),
                  Setoid.r a b → (fun f i => (Quotient.mk I) (f i)) a = (fun f i => (Quotient.mk I) (f i)) b),
          map_add' :=
            (_ :
              ∀ (x y : (ι → R) ⧸ pi I ι),
                (fun x =>
                      Quotient.liftOn' x (fun f i => (Quotient.mk I) (f i))
                        (_ :
                          ∀ (a b : ι → R),
                            Setoid.r a b → (fun f i => (Quotient.mk I) (f i)) a = (fun f i => (Quotient.mk I) (f i)) b))
                    (x + y) =
                  (fun x =>
                        Quotient.liftOn' x (fun f i => (Quotient.mk I) (f i))
                          (_ :
                            ∀ (a b : ι → R),
                              Setoid.r a b →
                                (fun f i => (Quotient.mk I) (f i)) a = (fun f i => (Quotient.mk I) (f i)) b))
                      x +
                    (fun x =>
                        Quotient.liftOn' x (fun f i => (Quotient.mk I) (f i))
                          (_ :
                            ∀ (a b : ι → R),
                              Setoid.r a b →
                                (fun f i => (Quotient.mk I) (f i)) a = (fun f i => (Quotient.mk I) (f i)) b))
                      y) }
        (Quot.mk Setoid.r a✝)

Next tactic:
rfl