l3lab/ntp-mathlib huggingface dataset:
/-- Quotienting by equal ideals gives equivalent rings.

See also `Submodule.quotEquivOfEq` and `Ideal.quotientEquivAlgOfEq`.
-/
def quotEquivOfEq {R : Type*} [CommRing R] {I J : Ideal R} (h : I = J) : R ⧸ I ≃+* R ⧸ J :=
  { Submodule.quotEquivOfEq I J h with
    map_mul' := by
      rintro ⟨x⟩ ⟨y⟩
      

Proof state:
case mk.mk
R✝ : Type u
inst✝¹ : CommRing R✝
I✝ : Ideal R✝
a b : R✝
S : Type v
R : Type u_1
inst✝ : CommRing R
I J : Ideal R
h : I = J
src✝ : (R ⧸ I) ≃ₗ[R] R ⧸ J := Submodule.quotEquivOfEq I J h
x✝ : R ⧸ I
x : R
y✝ : R ⧸ I
y : R
⊢ Equiv.toFun
      { toFun := src✝.toFun, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
        right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
      (Quot.mk Setoid.r x * Quot.mk Setoid.r y) =
    Equiv.toFun
        { toFun := src✝.toFun, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
          right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
        (Quot.mk Setoid.r x) *
      Equiv.toFun
        { toFun := src✝.toFun, invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
          right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
        (Quot.mk Setoid.r y)

Next tactic:
rfl
@[simp]
theorem quotEquivOfEq_symm {R : Type*} [CommRing R] {I J : Ideal R} (h : I = J) :
    (Ideal.quotEquivOfEq h).symm = Ideal.quotEquivOfEq h.symm := by 

Proof state:
R✝ : Type u
inst✝¹ : CommRing R✝
I✝ : Ideal R✝
a b : R✝
S : Type v
R : Type u_1
inst✝ : CommRing R
I J : Ideal R
h : I = J
⊢ RingEquiv.symm (quotEquivOfEq h) = quotEquivOfEq (_ : J = I)

Next tactic:
ext
@[simp]
theorem quotEquivOfEq_symm {R : Type*} [CommRing R] {I J : Ideal R} (h : I = J) :
    (Ideal.quotEquivOfEq h).symm = Ideal.quotEquivOfEq h.symm := by ext; 

Proof state:
case h
R✝ : Type u
inst✝¹ : CommRing R✝
I✝ : Ideal R✝
a b : R✝
S : Type v
R : Type u_1
inst✝ : CommRing R
I J : Ideal R
h : I = J
x✝ : R ⧸ J
⊢ (RingEquiv.symm (quotEquivOfEq h)) x✝ = (quotEquivOfEq (_ : J = I)) x✝

Next tactic:
rfl
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
c : R ⧸ I
m : (ι → R) ⧸ pi I ι
⊢ ∀ (a₁ : R) (a₂ : ι → R) (b₁ : R) (b₂ : ι → R),
    Setoid.r a₁ b₁ →
      Setoid.r a₂ b₂ →
        (fun r m => Submodule.Quotient.mk (r • m)) a₁ a₂ = (fun r m => Submodule.Quotient.mk (r • m)) b₁ b₂

Next tactic:
intro c₁ m₁ c₂ m₂ hc hm
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
c : R ⧸ I
m : (ι → R) ⧸ pi I ι
c₁ : R
m₁ : ι → R
c₂ : R
m₂ : ι → R
hc : Setoid.r c₁ c₂
hm : Setoid.r m₁ m₂
⊢ (fun r m => Submodule.Quotient.mk (r • m)) c₁ m₁ = (fun r m => Submodule.Quotient.mk (r • m)) c₂ m₂

Next tactic:
apply Ideal.Quotient.eq.2
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
c : R ⧸ I
m : (ι → R) ⧸ pi I ι
c₁ : R
m₁ : ι → R
c₂ : R
m₂ : ι → R
hc : Setoid.r c₁ c₂
hm : Setoid.r m₁ m₂
⊢ c₁ • m₁ - c₂ • m₂ ∈ pi I ι

Next tactic:
rw [Submodule.quotientRel_r_def] at hc hm
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
c : R ⧸ I
m : (ι → R) ⧸ pi I ι
c₁ : R
m₁ : ι → R
c₂ : R
m₂ : ι → R
hc : c₁ - c₂ ∈ I
hm : m₁ - m₂ ∈ pi I ι
⊢ c₁ • m₁ - c₂ • m₂ ∈ pi I ι

Next tactic:
intro i
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
c : R ⧸ I
m : (ι → R) ⧸ pi I ι
c₁ : R
m₁ : ι → R
c₂ : R
m₂ : ι → R
hc : c₁ - c₂ ∈ I
hm : m₁ - m₂ ∈ pi I ι
i : ι
⊢ (c₁ • m₁ - c₂ • m₂) i ∈ I

Next tactic:
exact I.mul_sub_mul_mem hc (hm i)
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
⊢ ∀ (b : (ι → R) ⧸ pi I ι), 1 • b = b

Next tactic:
rintro ⟨a⟩
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    

Proof state:
case mk
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b : R
S ι : Type v
b✝ : (ι → R) ⧸ pi I ι
a : ι → R
⊢ 1 • Quot.mk Setoid.r a = Quot.mk Setoid.r a

Next tactic:
convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    

Proof state:
case mk.convert_3
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b : R
S ι : Type v
b✝ : (ι → R) ⧸ pi I ι
a : ι → R
⊢ (Quotient.mk (pi I ι)) (1 • a) = (Quotient.mk (pi I ι)) a

Next tactic:
congr with i
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; 

Proof state:
case mk.convert_3.h.e_6.h.h
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b : R
S ι : Type v
b✝ : (ι → R) ⧸ pi I ι
a : ι → R
i : ι
⊢ (1 • a) i = a i

Next tactic:
exact one_mul (a i)
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
⊢ ∀ (x y : R ⧸ I) (b : (ι → R) ⧸ pi I ι), (x * y) • b = x • y • b

Next tactic:
rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    

Proof state:
case mk.mk.mk
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b✝¹ : R
S ι : Type v
x✝ : R ⧸ I
a : R
y✝ : R ⧸ I
b : R
b✝ : (ι → R) ⧸ pi I ι
c : ι → R
⊢ (Quot.mk Setoid.r a * Quot.mk Setoid.r b) • Quot.mk Setoid.r c =
    Quot.mk Setoid.r a • Quot.mk Setoid.r b • Quot.mk Setoid.r c

Next tactic:
convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    

Proof state:
case mk.mk.mk.convert_3
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b✝¹ : R
S ι : Type v
x✝ : R ⧸ I
a : R
y✝ : R ⧸ I
b : R
b✝ : (ι → R) ⧸ pi I ι
c : ι → R
⊢ (Quotient.mk (pi I ι)) ((fun x x_1 => x * x_1) a b • c) = (Quotient.mk (pi I ι)) (a • b • c)

Next tactic:
congr 1
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; 

Proof state:
case mk.mk.mk.convert_3.h.e_6.h
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b✝¹ : R
S ι : Type v
x✝ : R ⧸ I
a : R
y✝ : R ⧸ I
b : R
b✝ : (ι → R) ⧸ pi I ι
c : ι → R
⊢ (fun x x_1 => x * x_1) a b • c = a • b • c

Next tactic:
funext i
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; 

Proof state:
case mk.mk.mk.convert_3.h.e_6.h.h
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b✝¹ : R
S ι : Type v
x✝ : R ⧸ I
a : R
y✝ : R ⧸ I
b : R
b✝ : (ι → R) ⧸ pi I ι
c : ι → R
i : ι
⊢ ((fun x x_1 => x * x_1) a b • c) i = (a • b • c) i

Next tactic:
exact mul_assoc a b (c i)
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact mul_add a (b i) (c i)
  smul_zero := by
    

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
⊢ ∀ (a : R ⧸ I), a • 0 = 0

Next tactic:
rintro ⟨a⟩
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact mul_add a (b i) (c i)
  smul_zero := by
    rintro ⟨a⟩
    

Proof state:
case mk
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝¹ b : R
S ι : Type v
a✝ : R ⧸ I
a : R
⊢ Quot.mk Setoid.r a • 0 = 0

Next tactic:
convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact mul_add a (b i) (c i)
  smul_zero := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    

Proof state:
case mk.convert_3
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝¹ b : R
S ι : Type v
a✝ : R ⧸ I
a : R
⊢ (Quotient.mk (pi I ι)) (a • 0) = (Quotient.mk (pi I ι)) 0

Next tactic:
congr with _
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact mul_add a (b i) (c i)
  smul_zero := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with _; 

Proof state:
case mk.convert_3.h.e_6.h.h
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝¹ b : R
S ι : Type v
a✝ : R ⧸ I
a : R
x✝ : ι
⊢ (a • 0) x✝ = OfNat.ofNat 0 x✝

Next tactic:
exact mul_zero a
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
⊢ ∀ (a : R ⧸ I) (x y : (ι → R) ⧸ pi I ι), a • (x + y) = a • x + a • y

Next tactic:
rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    

Proof state:
case mk.mk.mk
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝¹ b✝ : R
S ι : Type v
a✝ : R ⧸ I
a : R
x✝ : (ι → R) ⧸ pi I ι
b : ι → R
y✝ : (ι → R) ⧸ pi I ι
c : ι → R
⊢ Quot.mk Setoid.r a • (Quot.mk Setoid.r b + Quot.mk Setoid.r c) =
    Quot.mk Setoid.r a • Quot.mk Setoid.r b + Quot.mk Setoid.r a • Quot.mk Setoid.r c

Next tactic:
convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    

Proof state:
case mk.mk.mk.convert_3
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝¹ b✝ : R
S ι : Type v
a✝ : R ⧸ I
a : R
x✝ : (ι → R) ⧸ pi I ι
b : ι → R
y✝ : (ι → R) ⧸ pi I ι
c : ι → R
⊢ (Quotient.mk (pi I ι)) (a • (fun x x_1 => x + x_1) b c) =
    (Quotient.mk (pi I ι)) ((fun x x_1 => x + x_1) (a • b) (a • c))

Next tactic:
congr with i
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; 

Proof state:
case mk.mk.mk.convert_3.h.e_6.h.h
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝¹ b✝ : R
S ι : Type v
a✝ : R ⧸ I
a : R
x✝ : (ι → R) ⧸ pi I ι
b : ι → R
y✝ : (ι → R) ⧸ pi I ι
c : ι → R
i : ι
⊢ (a • (fun x x_1 => x + x_1) b c) i = (fun x x_1 => x + x_1) (a • b) (a • c) i

Next tactic:
exact mul_add a (b i) (c i)
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact mul_add a (b i) (c i)
  smul_zero := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with _; exact mul_zero a
  add_smul := by
    

Proof state:
R : Type u
inst✝ : CommRing R
I : Ideal R
a b : R
S ι : Type v
⊢ ∀ (r s : R ⧸ I) (x : (ι → R) ⧸ pi I ι), (r + s) • x = r • x + s • x

Next tactic:
rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact mul_add a (b i) (c i)
  smul_zero := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with _; exact mul_zero a
  add_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    

Proof state:
case mk.mk.mk
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b✝ : R
S ι : Type v
r✝ : R ⧸ I
a : R
s✝ : R ⧸ I
b : R
x✝ : (ι → R) ⧸ pi I ι
c : ι → R
⊢ (Quot.mk Setoid.r a + Quot.mk Setoid.r b) • Quot.mk Setoid.r c =
    Quot.mk Setoid.r a • Quot.mk Setoid.r c + Quot.mk Setoid.r b • Quot.mk Setoid.r c

Next tactic:
convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
/-- `R^n/I^n` is a `R/I`-module. -/
instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where
  smul c m :=
    Quotient.liftOn₂' c m (fun r m => Submodule.Quotient.mk <| r • m) $ by
      intro c₁ m₁ c₂ m₂ hc hm
      apply Ideal.Quotient.eq.2
      rw [Submodule.quotientRel_r_def] at hc hm
      intro i
      exact I.mul_sub_mul_mem hc (hm i)
  one_smul := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact one_mul (a i)
  mul_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr 1; funext i; exact mul_assoc a b (c i)
  smul_add := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with i; exact mul_add a (b i) (c i)
  smul_zero := by
    rintro ⟨a⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    congr with _; exact mul_zero a
  add_smul := by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩
    convert_to Ideal.Quotient.mk (I.pi ι) _ = Ideal.Quotient.mk (I.pi ι) _
    

Proof state:
case mk.mk.mk.convert_3
R : Type u
inst✝ : CommRing R
I : Ideal R
a✝ b✝ : R
S ι : Type v
r✝ : R ⧸ I
a : R
s✝ : R ⧸ I
b : R
x✝ : (ι → R) ⧸ pi I ι
c : ι → R
⊢ (Quotient.mk (pi I ι)) ((fun x x_1 => x + x_1) a b • c) =
    (Quotient.mk (pi I ι)) ((fun x x_1 => x + x_1) (a • c) (b • c))

Next tactic:
congr with i