l3lab/ntp-mathlib huggingface dataset:
lemma quotientInfToPiQuotient_surj [Fintype ι] {I : ι → Ideal R}
    (hI : ∀ i j, i ≠ j → IsCoprime (I i) (I j)) : Surjective (quotientInfToPiQuotient I) := by
  classical
  intro g
  choose f hf using fun i ↦ mk_surjective (g i)
  have key : ∀ i, ∃ e : R, mk (I i) e = 1 ∧ ∀ j, j ≠ i → mk (I j) e = 0 := by
    intro i
    have hI' : ∀ j ∈ ({i} : Finset ι)ᶜ, IsCoprime (I i) (I j) := by
      intros j hj
      exact hI _ _ (by simpa [ne_comm, isCoprime_iff_add] using hj)
    rcases isCoprime_iff_exists.mp (isCoprime_biInf hI') with ⟨u, hu, e, he, hue⟩
    replace he : ∀ j, j ≠ i → e ∈ I j := by simpa using he
    refine ⟨e, ?_, ?_⟩
    · simp [eq_sub_of_add_eq' hue, map_sub, eq_zero_iff_mem.mpr hu]
      rfl
    · exact fun j hj ↦ eq_zero_iff_mem.mpr (he j hj)
  choose e he using key
  use mk _ (∑ i, f i*e i)
  ext i
  rw [quotientInfToPiQuotient_mk', map_sum, Fintype.sum_eq_single i]
  · 

Proof state:
case h.h
R : Type u
S : Type v
F : Type w
inst✝² : CommRing R
inst✝¹ : CommRing S
ι : Type u_1
inst✝ : Fintype ι
I : ι → Ideal R
hI : ∀ (i j : ι), i ≠ j → IsCoprime (I i) (I j)
g : (i : ι) → R ⧸ I i
f : ι → R
hf : ∀ (i : ι), (Quotient.mk (I i)) (f i) = g i
e : ι → R
he : ∀ (i : ι), (Quotient.mk (I i)) (e i) = 1 ∧ ∀ (j : ι), j ≠ i → (Quotient.mk (I j)) (e i) = 0
i : ι
⊢ (Quotient.mk (I i)) (f i * e i) = g i

Next tactic:
simp [(he i).1, hf]
lemma quotientInfToPiQuotient_surj [Fintype ι] {I : ι → Ideal R}
    (hI : ∀ i j, i ≠ j → IsCoprime (I i) (I j)) : Surjective (quotientInfToPiQuotient I) := by
  classical
  intro g
  choose f hf using fun i ↦ mk_surjective (g i)
  have key : ∀ i, ∃ e : R, mk (I i) e = 1 ∧ ∀ j, j ≠ i → mk (I j) e = 0 := by
    intro i
    have hI' : ∀ j ∈ ({i} : Finset ι)ᶜ, IsCoprime (I i) (I j) := by
      intros j hj
      exact hI _ _ (by simpa [ne_comm, isCoprime_iff_add] using hj)
    rcases isCoprime_iff_exists.mp (isCoprime_biInf hI') with ⟨u, hu, e, he, hue⟩
    replace he : ∀ j, j ≠ i → e ∈ I j := by simpa using he
    refine ⟨e, ?_, ?_⟩
    · simp [eq_sub_of_add_eq' hue, map_sub, eq_zero_iff_mem.mpr hu]
      rfl
    · exact fun j hj ↦ eq_zero_iff_mem.mpr (he j hj)
  choose e he using key
  use mk _ (∑ i, f i*e i)
  ext i
  rw [quotientInfToPiQuotient_mk', map_sum, Fintype.sum_eq_single i]
  · simp [(he i).1, hf]
  · 

Proof state:
case h.h
R : Type u
S : Type v
F : Type w
inst✝² : CommRing R
inst✝¹ : CommRing S
ι : Type u_1
inst✝ : Fintype ι
I : ι → Ideal R
hI : ∀ (i j : ι), i ≠ j → IsCoprime (I i) (I j)
g : (i : ι) → R ⧸ I i
f : ι → R
hf : ∀ (i : ι), (Quotient.mk (I i)) (f i) = g i
e : ι → R
he : ∀ (i : ι), (Quotient.mk (I i)) (e i) = 1 ∧ ∀ (j : ι), j ≠ i → (Quotient.mk (I j)) (e i) = 0
i : ι
⊢ ∀ (x : ι), x ≠ i → (Quotient.mk (I i)) (f x * e x) = 0

Next tactic:
intros j hj
lemma quotientInfToPiQuotient_surj [Fintype ι] {I : ι → Ideal R}
    (hI : ∀ i j, i ≠ j → IsCoprime (I i) (I j)) : Surjective (quotientInfToPiQuotient I) := by
  classical
  intro g
  choose f hf using fun i ↦ mk_surjective (g i)
  have key : ∀ i, ∃ e : R, mk (I i) e = 1 ∧ ∀ j, j ≠ i → mk (I j) e = 0 := by
    intro i
    have hI' : ∀ j ∈ ({i} : Finset ι)ᶜ, IsCoprime (I i) (I j) := by
      intros j hj
      exact hI _ _ (by simpa [ne_comm, isCoprime_iff_add] using hj)
    rcases isCoprime_iff_exists.mp (isCoprime_biInf hI') with ⟨u, hu, e, he, hue⟩
    replace he : ∀ j, j ≠ i → e ∈ I j := by simpa using he
    refine ⟨e, ?_, ?_⟩
    · simp [eq_sub_of_add_eq' hue, map_sub, eq_zero_iff_mem.mpr hu]
      rfl
    · exact fun j hj ↦ eq_zero_iff_mem.mpr (he j hj)
  choose e he using key
  use mk _ (∑ i, f i*e i)
  ext i
  rw [quotientInfToPiQuotient_mk', map_sum, Fintype.sum_eq_single i]
  · simp [(he i).1, hf]
  · intros j hj
    

Proof state:
case h.h
R : Type u
S : Type v
F : Type w
inst✝² : CommRing R
inst✝¹ : CommRing S
ι : Type u_1
inst✝ : Fintype ι
I : ι → Ideal R
hI : ∀ (i j : ι), i ≠ j → IsCoprime (I i) (I j)
g : (i : ι) → R ⧸ I i
f : ι → R
hf : ∀ (i : ι), (Quotient.mk (I i)) (f i) = g i
e : ι → R
he : ∀ (i : ι), (Quotient.mk (I i)) (e i) = 1 ∧ ∀ (j : ι), j ≠ i → (Quotient.mk (I j)) (e i) = 0
i j : ι
hj : j ≠ i
⊢ (Quotient.mk (I i)) (f j * e j) = 0

Next tactic:
simp [(he j).2 i hj.symm]
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    

Proof state:
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
⊢ ∀ (i j : Fin 2), i ≠ j → IsCoprime (f i) (f j)

Next tactic:
intro i j h
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    

Proof state:
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
i j : Fin 2
h : i ≠ j
⊢ IsCoprime (f i) (f j)

Next tactic:
fin_cases i
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> 

Proof state:
case head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
j : Fin 2
h : { val := 0, isLt := (_ : 0 < 2) } ≠ j
⊢ IsCoprime (f { val := 0, isLt := (_ : 0 < 2) }) (f j)

Next tactic:
fin_cases j
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> 

Proof state:
case tail.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
j : Fin 2
h : { val := 1, isLt := (_ : (fun a => a < 2) 1) } ≠ j
⊢ IsCoprime (f { val := 1, isLt := (_ : (fun a => a < 2) 1) }) (f j)

Next tactic:
fin_cases j
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> 

Proof state:
case head.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 0, isLt := (_ : 0 < 2) } ≠ { val := 0, isLt := (_ : 0 < 2) }
⊢ IsCoprime (f { val := 0, isLt := (_ : 0 < 2) }) (f { val := 0, isLt := (_ : 0 < 2) })

Next tactic:
try contradiction
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> try 

Proof state:
case head.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 0, isLt := (_ : 0 < 2) } ≠ { val := 0, isLt := (_ : 0 < 2) }
⊢ IsCoprime (f { val := 0, isLt := (_ : 0 < 2) }) (f { val := 0, isLt := (_ : 0 < 2) })

Next tactic:
contradiction
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> 

Proof state:
case head.tail.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 0, isLt := (_ : 0 < 2) } ≠ { val := 1, isLt := (_ : (fun a => a < 2) 1) }
⊢ IsCoprime (f { val := 0, isLt := (_ : 0 < 2) }) (f { val := 1, isLt := (_ : (fun a => a < 2) 1) })

Next tactic:
try contradiction
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> try 

Proof state:
case head.tail.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 0, isLt := (_ : 0 < 2) } ≠ { val := 1, isLt := (_ : (fun a => a < 2) 1) }
⊢ IsCoprime (f { val := 0, isLt := (_ : 0 < 2) }) (f { val := 1, isLt := (_ : (fun a => a < 2) 1) })

Next tactic:
contradiction
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> 

Proof state:
case tail.head.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 1, isLt := (_ : (fun a => a < 2) 1) } ≠ { val := 0, isLt := (_ : 0 < 2) }
⊢ IsCoprime (f { val := 1, isLt := (_ : (fun a => a < 2) 1) }) (f { val := 0, isLt := (_ : 0 < 2) })

Next tactic:
try contradiction
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> try 

Proof state:
case tail.head.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 1, isLt := (_ : (fun a => a < 2) 1) } ≠ { val := 0, isLt := (_ : 0 < 2) }
⊢ IsCoprime (f { val := 1, isLt := (_ : (fun a => a < 2) 1) }) (f { val := 0, isLt := (_ : 0 < 2) })

Next tactic:
contradiction
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> 

Proof state:
case tail.head.tail.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 1, isLt := (_ : (fun a => a < 2) 1) } ≠ { val := 1, isLt := (_ : (fun a => a < 2) 1) }
⊢ IsCoprime (f { val := 1, isLt := (_ : (fun a => a < 2) 1) }) (f { val := 1, isLt := (_ : (fun a => a < 2) 1) })

Next tactic:
try contradiction
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> try 

Proof state:
case tail.head.tail.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 1, isLt := (_ : (fun a => a < 2) 1) } ≠ { val := 1, isLt := (_ : (fun a => a < 2) 1) }
⊢ IsCoprime (f { val := 1, isLt := (_ : (fun a => a < 2) 1) }) (f { val := 1, isLt := (_ : (fun a => a < 2) 1) })

Next tactic:
contradiction
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> try contradiction
    · 

Proof state:
case head.tail.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 0, isLt := (_ : 0 < 2) } ≠ { val := 1, isLt := (_ : (fun a => a < 2) 1) }
⊢ IsCoprime (f { val := 0, isLt := (_ : 0 < 2) }) (f { val := 1, isLt := (_ : (fun a => a < 2) 1) })

Next tactic:
assumption
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> try contradiction
    · assumption
    · 

Proof state:
case tail.head.head
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
h : { val := 1, isLt := (_ : (fun a => a < 2) 1) } ≠ { val := 0, isLt := (_ : 0 < 2) }
⊢ IsCoprime (f { val := 1, isLt := (_ : (fun a => a < 2) 1) }) (f { val := 0, isLt := (_ : 0 < 2) })

Next tactic:
exact coprime.symm
/-- **Chinese remainder theorem**, specialized to two ideals. -/
noncomputable def quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    R ⧸ I ⊓ J ≃+* (R ⧸ I) × R ⧸ J :=
  let f : Fin 2 → Ideal R := ![I, J]
  have hf : ∀ i j : Fin 2, i ≠ j → IsCoprime (f i) (f j) := by
    intro i j h
    fin_cases i <;> fin_cases j <;> try contradiction
    · assumption
    · exact coprime.symm
  (Ideal.quotEquivOfEq (by 

Proof state:
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
f : Fin 2 → Ideal R := ![I, J]
hf : ∀ (i j : Fin 2), i ≠ j → IsCoprime (f i) (f j)
⊢ I ⊓ J = ⨅ i, f i

Next tactic:
simp [iInf, inf_comm]
@[simp]
theorem fst_comp_quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    (RingHom.fst _ _).comp
        (quotientInfEquivQuotientProd I J coprime : R ⧸ I ⊓ J →+* (R ⧸ I) × R ⧸ J) =
      Ideal.Quotient.factor (I ⊓ J) I inf_le_left := by
  

Proof state:
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
⊢ RingHom.comp (fst (R ⧸ I) (R ⧸ J)) ↑(quotientInfEquivQuotientProd I J coprime) = factor (I ⊓ J) I (_ : I ⊓ J ≤ I)

Next tactic:
apply Quotient.ringHom_ext
@[simp]
theorem fst_comp_quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    (RingHom.fst _ _).comp
        (quotientInfEquivQuotientProd I J coprime : R ⧸ I ⊓ J →+* (R ⧸ I) × R ⧸ J) =
      Ideal.Quotient.factor (I ⊓ J) I inf_le_left := by
  apply Quotient.ringHom_ext; 

Proof state:
case h
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
⊢ RingHom.comp (RingHom.comp (fst (R ⧸ I) (R ⧸ J)) ↑(quotientInfEquivQuotientProd I J coprime)) (Quotient.mk (I ⊓ J)) =
    RingHom.comp (factor (I ⊓ J) I (_ : I ⊓ J ≤ I)) (Quotient.mk (I ⊓ J))

Next tactic:
ext
@[simp]
theorem fst_comp_quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    (RingHom.fst _ _).comp
        (quotientInfEquivQuotientProd I J coprime : R ⧸ I ⊓ J →+* (R ⧸ I) × R ⧸ J) =
      Ideal.Quotient.factor (I ⊓ J) I inf_le_left := by
  apply Quotient.ringHom_ext; ext; 

Proof state:
case h.a
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
x✝ : R
⊢ (RingHom.comp (RingHom.comp (fst (R ⧸ I) (R ⧸ J)) ↑(quotientInfEquivQuotientProd I J coprime)) (Quotient.mk (I ⊓ J)))
      x✝ =
    (RingHom.comp (factor (I ⊓ J) I (_ : I ⊓ J ≤ I)) (Quotient.mk (I ⊓ J))) x✝

Next tactic:
rfl
@[simp]
theorem snd_comp_quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    (RingHom.snd _ _).comp
        (quotientInfEquivQuotientProd I J coprime : R ⧸ I ⊓ J →+* (R ⧸ I) × R ⧸ J) =
      Ideal.Quotient.factor (I ⊓ J) J inf_le_right := by
  

Proof state:
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
⊢ RingHom.comp (snd (R ⧸ I) (R ⧸ J)) ↑(quotientInfEquivQuotientProd I J coprime) = factor (I ⊓ J) J (_ : I ⊓ J ≤ J)

Next tactic:
apply Quotient.ringHom_ext
@[simp]
theorem snd_comp_quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    (RingHom.snd _ _).comp
        (quotientInfEquivQuotientProd I J coprime : R ⧸ I ⊓ J →+* (R ⧸ I) × R ⧸ J) =
      Ideal.Quotient.factor (I ⊓ J) J inf_le_right := by
  apply Quotient.ringHom_ext; 

Proof state:
case h
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
⊢ RingHom.comp (RingHom.comp (snd (R ⧸ I) (R ⧸ J)) ↑(quotientInfEquivQuotientProd I J coprime)) (Quotient.mk (I ⊓ J)) =
    RingHom.comp (factor (I ⊓ J) J (_ : I ⊓ J ≤ J)) (Quotient.mk (I ⊓ J))

Next tactic:
ext
@[simp]
theorem snd_comp_quotientInfEquivQuotientProd (I J : Ideal R) (coprime : IsCoprime I J) :
    (RingHom.snd _ _).comp
        (quotientInfEquivQuotientProd I J coprime : R ⧸ I ⊓ J →+* (R ⧸ I) × R ⧸ J) =
      Ideal.Quotient.factor (I ⊓ J) J inf_le_right := by
  apply Quotient.ringHom_ext; ext; 

Proof state:
case h.a
R : Type u
S : Type v
F : Type w
inst✝¹ : CommRing R
inst✝ : CommRing S
ι : Type u_1
I J : Ideal R
coprime : IsCoprime I J
x✝ : R
⊢ (RingHom.comp (RingHom.comp (snd (R ⧸ I) (R ⧸ J)) ↑(quotientInfEquivQuotientProd I J coprime)) (Quotient.mk (I ⊓ J)))
      x✝ =
    (RingHom.comp (factor (I ⊓ J) J (_ : I ⊓ J ≤ J)) (Quotient.mk (I ⊓ J))) x✝

Next tactic:
rfl
instance Quotient.isScalarTower [SMul R₁ R₂] [IsScalarTower R₁ R₂ A] (I : Ideal A) :
    IsScalarTower R₁ R₂ (A ⧸ I) := by 

Proof state:
R : Type u
S : Type v
F : Type w
inst✝¹⁰ : CommRing R
inst✝⁹ : CommRing S
R₁ : Type u_1
R₂ : Type u_2
A : Type u_3
B : Type u_4
inst✝⁸ : CommSemiring R₁
inst✝⁷ : CommSemiring R₂
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra R₁ A
inst✝³ : Algebra R₂ A
inst✝² : Algebra R₁ B
inst✝¹ : SMul R₁ R₂
inst✝ : IsScalarTower R₁ R₂ A
I : Ideal A
⊢ IsScalarTower R₁ R₂ (A ⧸ I)

Next tactic:
infer_instance
/-- `Ideal.quotient.lift` as an `AlgHom`. -/
def Quotient.liftₐ (I : Ideal A) (f : A →ₐ[R₁] B) (hI : ∀ a : A, a ∈ I → f a = 0) :
    A ⧸ I →ₐ[R₁] B :=
  {-- this is IsScalarTower.algebraMap_apply R₁ A (A ⧸ I) but the file `Algebra.Algebra.Tower`
      -- imports this file.
      Ideal.Quotient.lift
      I (f : A →+* B) hI with
    commutes' := fun r => by
      

Proof state:
R : Type u
S : Type v
F : Type w
inst✝⁸ : CommRing R
inst✝⁷ : CommRing S
R₁ : Type u_1
R₂ : Type u_2
A : Type u_3
B : Type u_4
inst✝⁶ : CommSemiring R₁
inst✝⁵ : CommSemiring R₂
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R₁ A
inst✝¹ : Algebra R₂ A
inst✝ : Algebra R₁ B
I : Ideal A
f : A →ₐ[R₁] B
hI : ∀ a ∈ I, f a = 0
src✝ : A ⧸ I →+* B := lift I (↑f) hI
r : R₁
⊢ OneHom.toFun
      (↑↑{ toMonoidHom := ↑src✝, map_zero' := (_ : OneHom.toFun (↑↑src✝) 0 = 0),
            map_add' :=
              (_ :
                ∀ (x y : A ⧸ I), OneHom.toFun (↑↑src✝) (x + y) = OneHom.toFun (↑↑src✝) x + OneHom.toFun (↑↑src✝) y) })
      ((algebraMap R₁ (A ⧸ I)) r) =
    (algebraMap R₁ B) r

Next tactic:
have : algebraMap R₁ (A ⧸ I) r = algebraMap A (A ⧸ I) (algebraMap R₁ A r) := by
        simp_rw [Algebra.algebraMap_eq_smul_one, smul_assoc, one_smul]
/-- `Ideal.quotient.lift` as an `AlgHom`. -/
def Quotient.liftₐ (I : Ideal A) (f : A →ₐ[R₁] B) (hI : ∀ a : A, a ∈ I → f a = 0) :
    A ⧸ I →ₐ[R₁] B :=
  {-- this is IsScalarTower.algebraMap_apply R₁ A (A ⧸ I) but the file `Algebra.Algebra.Tower`
      -- imports this file.
      Ideal.Quotient.lift
      I (f : A →+* B) hI with
    commutes' := fun r => by
      have : algebraMap R₁ (A ⧸ I) r = algebraMap A (A ⧸ I) (algebraMap R₁ A r) := by
        

Proof state:
R : Type u
S : Type v
F : Type w
inst✝⁸ : CommRing R
inst✝⁷ : CommRing S
R₁ : Type u_1
R₂ : Type u_2
A : Type u_3
B : Type u_4
inst✝⁶ : CommSemiring R₁
inst✝⁵ : CommSemiring R₂
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R₁ A
inst✝¹ : Algebra R₂ A
inst✝ : Algebra R₁ B
I : Ideal A
f : A →ₐ[R₁] B
hI : ∀ a ∈ I, f a = 0
src✝ : A ⧸ I →+* B := lift I (↑f) hI
r : R₁
⊢ (algebraMap R₁ (A ⧸ I)) r = (algebraMap A (A ⧸ I)) ((algebraMap R₁ A) r)

Next tactic:
simp_rw [Algebra.algebraMap_eq_smul_one, smul_assoc, one_smul]
/-- `Ideal.quotient.lift` as an `AlgHom`. -/
def Quotient.liftₐ (I : Ideal A) (f : A →ₐ[R₁] B) (hI : ∀ a : A, a ∈ I → f a = 0) :
    A ⧸ I →ₐ[R₁] B :=
  {-- this is IsScalarTower.algebraMap_apply R₁ A (A ⧸ I) but the file `Algebra.Algebra.Tower`
      -- imports this file.
      Ideal.Quotient.lift
      I (f : A →+* B) hI with
    commutes' := fun r => by
      have : algebraMap R₁ (A ⧸ I) r = algebraMap A (A ⧸ I) (algebraMap R₁ A r) := by
        simp_rw [Algebra.algebraMap_eq_smul_one, smul_assoc, one_smul]
      

Proof state:
R : Type u
S : Type v
F : Type w
inst✝⁸ : CommRing R
inst✝⁷ : CommRing S
R₁ : Type u_1
R₂ : Type u_2
A : Type u_3
B : Type u_4
inst✝⁶ : CommSemiring R₁
inst✝⁵ : CommSemiring R₂
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R₁ A
inst✝¹ : Algebra R₂ A
inst✝ : Algebra R₁ B
I : Ideal A
f : A →ₐ[R₁] B
hI : ∀ a ∈ I, f a = 0
src✝ : A ⧸ I →+* B := lift I (↑f) hI
r : R₁
this : (algebraMap R₁ (A ⧸ I)) r = (algebraMap A (A ⧸ I)) ((algebraMap R₁ A) r)
⊢ OneHom.toFun
      (↑↑{ toMonoidHom := ↑src✝, map_zero' := (_ : OneHom.toFun (↑↑src✝) 0 = 0),
            map_add' :=
              (_ :
                ∀ (x y : A ⧸ I), OneHom.toFun (↑↑src✝) (x + y) = OneHom.toFun (↑↑src✝) x + OneHom.toFun (↑↑src✝) y) })
      ((algebraMap R₁ (A ⧸ I)) r) =
    (algebraMap R₁ B) r

Next tactic:
rw [this, Ideal.Quotient.algebraMap_eq, RingHom.toFun_eq_coe, Ideal.Quotient.lift_mk,
        AlgHom.coe_toRingHom, Algebra.algebraMap_eq_smul_one, Algebra.algebraMap_eq_smul_one,
        map_smul, map_one]
theorem KerLift.map_smul (f : A →ₐ[R₁] B) (r : R₁) (x : A ⧸ (RingHom.ker f.toRingHom)) :
    f.toRingHom.kerLift (r • x) = r • f.toRingHom.kerLift x := by
  

Proof state:
R : Type u
S : Type v
F : Type w
inst✝⁸ : CommRing R
inst✝⁷ : CommRing S
R₁ : Type u_1
R₂ : Type u_2
A : Type u_3
B : Type u_4
inst✝⁶ : CommSemiring R₁
inst✝⁵ : CommSemiring R₂
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R₁ A
inst✝¹ : Algebra R₂ A
inst✝ : Algebra R₁ B
f : A →ₐ[R₁] B
r : R₁
x : A ⧸ ker ↑f
⊢ (kerLift ↑f) (r • x) = r • (kerLift ↑f) x

Next tactic:
obtain ⟨a, rfl⟩ := Quotient.mkₐ_surjective R₁ _ x
theorem KerLift.map_smul (f : A →ₐ[R₁] B) (r : R₁) (x : A ⧸ (RingHom.ker f.toRingHom)) :
    f.toRingHom.kerLift (r • x) = r • f.toRingHom.kerLift x := by
  obtain ⟨a, rfl⟩ := Quotient.mkₐ_surjective R₁ _ x
  

Proof state:
case intro
R : Type u
S : Type v
F : Type w
inst✝⁸ : CommRing R
inst✝⁷ : CommRing S
R₁ : Type u_1
R₂ : Type u_2
A : Type u_3
B : Type u_4
inst✝⁶ : CommSemiring R₁
inst✝⁵ : CommSemiring R₂
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R₁ A
inst✝¹ : Algebra R₂ A
inst✝ : Algebra R₁ B
f : A →ₐ[R₁] B
r : R₁
a : A
⊢ (kerLift ↑f) (r • (Quotient.mkₐ R₁ (ker ↑f)) a) = r • (kerLift ↑f) ((Quotient.mkₐ R₁ (ker ↑f)) a)

Next tactic:
exact f.map_smul _ _