/-- `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 

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
⊢ ∀ (r : R ⧸ I) (x : (ι → R) ⧸ pi I ι),
    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) }
        (r • x) =
      (RingHom.id (R ⧸ I)) 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) }
          x

Next tactic:
rintro ⟨_⟩ ⟨_⟩