l3lab/ntp-mathlib huggingface dataset:
/-- The algebra equiv `A/I ≃ₐ[R] B/J` induced by an algebra equiv `f : A ≃ₐ[R] B`,
where`J = f(I)`. -/
def quotientEquivAlg (I : Ideal A) (J : Ideal B) (f : A ≃ₐ[R₁] B) (hIJ : J = I.map (f : A →+* B)) :
    (A ⧸ I) ≃ₐ[R₁] B ⧸ J :=
  { quotientEquiv I J (f : A ≃+* B) hIJ with
    commutes' := fun r => by
      -- Porting note: Needed to add the below lemma because Equivs coerce weird
      have : ∀ (e : RingEquiv (A ⧸ I) (B ⧸ J)), Equiv.toFun e.toEquiv = FunLike.coe e := fun _ ↦ rfl
      rw [this]
      

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
J : Ideal B
f : A ≃ₐ[R₁] B
hIJ : J = map (↑f) I
src✝ : A ⧸ I ≃+* B ⧸ J := quotientEquiv I J (↑f) hIJ
r : R₁
this : ∀ (e : A ⧸ I ≃+* B ⧸ J), e.toFun = ⇑e
⊢ src✝ ((algebraMap R₁ (A ⧸ I)) r) = (algebraMap R₁ (B ⧸ J)) r

Next tactic:
simp only [quotientEquiv_apply, RingHom.toFun_eq_coe, quotientMap_algebraMap,
      RingEquiv.coe_toRingHom, AlgEquiv.coe_ringEquiv, AlgEquiv.commutes, Quotient.mk_algebraMap]
theorem algebraMap_quotient_injective {I : Ideal A} [Algebra R A] :
    Function.Injective (algebraMap (R ⧸ I.comap (algebraMap R A)) (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
I : Ideal A
inst✝ : Algebra R A
⊢ Injective ⇑(algebraMap (R ⧸ comap (algebraMap R A) I) (A ⧸ I))

Next tactic:
rintro ⟨a⟩ ⟨b⟩ hab
theorem algebraMap_quotient_injective {I : Ideal A} [Algebra R A] :
    Function.Injective (algebraMap (R ⧸ I.comap (algebraMap R A)) (A ⧸ I)) := by
  rintro ⟨a⟩ ⟨b⟩ hab
  

Proof state:
case mk.mk
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
inst✝ : Algebra R A
a₁✝ : R ⧸ comap (algebraMap R A) I
a : R
a₂✝ : R ⧸ comap (algebraMap R A) I
b : R
hab :
  (algebraMap (R ⧸ comap (algebraMap R A) I) (A ⧸ I)) (Quot.mk Setoid.r a) =
    (algebraMap (R ⧸ comap (algebraMap R A) I) (A ⧸ I)) (Quot.mk Setoid.r b)
⊢ Quot.mk Setoid.r a = Quot.mk Setoid.r b

Next tactic:
replace hab := Quotient.eq.mp hab
theorem algebraMap_quotient_injective {I : Ideal A} [Algebra R A] :
    Function.Injective (algebraMap (R ⧸ I.comap (algebraMap R A)) (A ⧸ I)) := by
  rintro ⟨a⟩ ⟨b⟩ hab
  replace hab := Quotient.eq.mp hab
  

Proof state:
case mk.mk
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
inst✝ : Algebra R A
a₁✝ : R ⧸ comap (algebraMap R A) I
a : R
a₂✝ : R ⧸ comap (algebraMap R A) I
b : R
hab : (algebraMap R A) a - (algebraMap R A) b ∈ I
⊢ Quot.mk Setoid.r a = Quot.mk Setoid.r b

Next tactic:
rw [← RingHom.map_sub] at hab
theorem algebraMap_quotient_injective {I : Ideal A} [Algebra R A] :
    Function.Injective (algebraMap (R ⧸ I.comap (algebraMap R A)) (A ⧸ I)) := by
  rintro ⟨a⟩ ⟨b⟩ hab
  replace hab := Quotient.eq.mp hab
  rw [← RingHom.map_sub] at hab
  

Proof state:
case mk.mk
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
inst✝ : Algebra R A
a₁✝ : R ⧸ comap (algebraMap R A) I
a : R
a₂✝ : R ⧸ comap (algebraMap R A) I
b : R
hab : (algebraMap R A) (a - b) ∈ I
⊢ Quot.mk Setoid.r a = Quot.mk Setoid.r b

Next tactic:
exact Quotient.eq.mpr hab
@[simp]
theorem quotientEquivAlgOfEq_symm {I J : Ideal A} (h : I = J) :
    (quotientEquivAlgOfEq R₁ h).symm = quotientEquivAlgOfEq R₁ h.symm := 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 J : Ideal A
h : I = J
⊢ AlgEquiv.symm (quotientEquivAlgOfEq R₁ h) = quotientEquivAlgOfEq R₁ (_ : J = I)

Next tactic:
ext
@[simp]
theorem quotientEquivAlgOfEq_symm {I J : Ideal A} (h : I = J) :
    (quotientEquivAlgOfEq R₁ h).symm = quotientEquivAlgOfEq R₁ h.symm := by
  ext
  

Proof state:
case h
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 J : Ideal A
h : I = J
a✝ : A ⧸ J
⊢ (AlgEquiv.symm (quotientEquivAlgOfEq R₁ h)) a✝ = (quotientEquivAlgOfEq R₁ (_ : J = I)) a✝

Next tactic:
rfl
lemma comap_map_mk {I J : Ideal R} (h : I ≤ J) :
    Ideal.comap (Ideal.Quotient.mk I) (Ideal.map (Ideal.Quotient.mk I) J) = J :=
  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 J : Ideal R
h : I ≤ J
⊢ comap (Quotient.mk I) (map (Quotient.mk I) J) = J

Next tactic:
ext
lemma comap_map_mk {I J : Ideal R} (h : I ≤ J) :
    Ideal.comap (Ideal.Quotient.mk I) (Ideal.map (Ideal.Quotient.mk I) J) = J :=
  by ext; 

Proof state:
case h
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 J : Ideal R
h : I ≤ J
x✝ : R
⊢ x✝ ∈ comap (Quotient.mk I) (map (Quotient.mk I) J) ↔ x✝ ∈ J

Next tactic:
rw [← Ideal.mem_quotient_iff_mem h, Ideal.mem_comap]
/-- The kernel of `quotLeftToQuotSup` -/
theorem ker_quotLeftToQuotSup : RingHom.ker (quotLeftToQuotSup I J) =
    J.map (Ideal.Quotient.mk I) := by
  

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.ker (quotLeftToQuotSup I J) = map (Ideal.Quotient.mk I) J

Next tactic:
simp only [mk_ker, sup_idem, sup_comm, quotLeftToQuotSup, Quotient.factor, ker_quotient_lift,
    map_eq_iff_sup_ker_eq_of_surjective (Ideal.Quotient.mk I) Quotient.mk_surjective, ← sup_assoc]
/-- The kernel of `quotQuotMk` -/
theorem ker_quotQuotMk : RingHom.ker (quotQuotMk I J) = I ⊔ J := by
  

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.ker (quotQuotMk I J) = I ⊔ J

Next tactic:
rw [RingHom.ker_eq_comap_bot, quotQuotMk, ← comap_comap, ← RingHom.ker, mk_ker,
    comap_map_of_surjective (Ideal.Quotient.mk I) Quotient.mk_surjective, ← RingHom.ker, mk_ker,
    sup_comm]
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp ↑(liftSupQuotQuotMk I J) ↑(quotQuotToQuotSup I J) = RingHom.id ((R ⧸ I) ⧸ map (Ideal.Quotient.mk I) J)

Next tactic:
repeat apply Ideal.Quotient.ringHom_ext
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      repeat 

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp ↑(liftSupQuotQuotMk I J) ↑(quotQuotToQuotSup I J) = RingHom.id ((R ⧸ I) ⧸ map (Ideal.Quotient.mk I) J)

Next tactic:
apply Ideal.Quotient.ringHom_ext
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      repeat 

Proof state:
case h
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp (RingHom.comp ↑(liftSupQuotQuotMk I J) ↑(quotQuotToQuotSup I J))
      (Ideal.Quotient.mk (map (Ideal.Quotient.mk I) J)) =
    RingHom.comp (RingHom.id ((R ⧸ I) ⧸ map (Ideal.Quotient.mk I) J)) (Ideal.Quotient.mk (map (Ideal.Quotient.mk I) J))

Next tactic:
apply Ideal.Quotient.ringHom_ext
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      repeat 

Proof state:
case h.h
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp
      (RingHom.comp (RingHom.comp ↑(liftSupQuotQuotMk I J) ↑(quotQuotToQuotSup I J))
        (Ideal.Quotient.mk (map (Ideal.Quotient.mk I) J)))
      (Ideal.Quotient.mk I) =
    RingHom.comp
      (RingHom.comp (RingHom.id ((R ⧸ I) ⧸ map (Ideal.Quotient.mk I) J))
        (Ideal.Quotient.mk (map (Ideal.Quotient.mk I) J)))
      (Ideal.Quotient.mk I)

Next tactic:
apply Ideal.Quotient.ringHom_ext
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      repeat apply Ideal.Quotient.ringHom_ext
      

Proof state:
case h.h
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp
      (RingHom.comp (RingHom.comp ↑(liftSupQuotQuotMk I J) ↑(quotQuotToQuotSup I J))
        (Ideal.Quotient.mk (map (Ideal.Quotient.mk I) J)))
      (Ideal.Quotient.mk I) =
    RingHom.comp
      (RingHom.comp (RingHom.id ((R ⧸ I) ⧸ map (Ideal.Quotient.mk I) J))
        (Ideal.Quotient.mk (map (Ideal.Quotient.mk I) J)))
      (Ideal.Quotient.mk I)

Next tactic:
rfl
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      repeat apply Ideal.Quotient.ringHom_ext
      rfl)
    (by
      

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp ↑(quotQuotToQuotSup I J) ↑(liftSupQuotQuotMk I J) = RingHom.id (R ⧸ I ⊔ J)

Next tactic:
repeat apply Ideal.Quotient.ringHom_ext
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      repeat apply Ideal.Quotient.ringHom_ext
      rfl)
    (by
      repeat 

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp ↑(quotQuotToQuotSup I J) ↑(liftSupQuotQuotMk I J) = RingHom.id (R ⧸ I ⊔ J)

Next tactic:
apply Ideal.Quotient.ringHom_ext
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      repeat apply Ideal.Quotient.ringHom_ext
      rfl)
    (by
      repeat 

Proof state:
case h
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp (RingHom.comp ↑(quotQuotToQuotSup I J) ↑(liftSupQuotQuotMk I J)) (Ideal.Quotient.mk (I ⊔ J)) =
    RingHom.comp (RingHom.id (R ⧸ I ⊔ J)) (Ideal.Quotient.mk (I ⊔ J))

Next tactic:
apply Ideal.Quotient.ringHom_ext
/-- `quotQuotToQuotSup` and `liftSupQuotQuotMk` are inverse isomorphisms. In the case where
    `I ≤ J`, this is the Third Isomorphism Theorem (see `quotQuotEquivQuotOfLe`)-/
def quotQuotEquivQuotSup : (R ⧸ I) ⧸ J.map (Ideal.Quotient.mk I) ≃+* R ⧸ I ⊔ J :=
  RingEquiv.ofHomInv (quotQuotToQuotSup I J) (liftSupQuotQuotMk I J)
    (by
      repeat apply Ideal.Quotient.ringHom_ext
      rfl)
    (by
      repeat apply Ideal.Quotient.ringHom_ext
      

Proof state:
case h
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingHom.comp (RingHom.comp ↑(quotQuotToQuotSup I J) ↑(liftSupQuotQuotMk I J)) (Ideal.Quotient.mk (I ⊔ J)) =
    RingHom.comp (RingHom.id (R ⧸ I ⊔ J)) (Ideal.Quotient.mk (I ⊔ J))

Next tactic:
rfl
@[simp]
theorem quotQuotEquivComm_symm : (quotQuotEquivComm I J).symm = quotQuotEquivComm J I := by
  /-  Porting note: this proof used to just be rfl but currently rfl opens up a bottomless pit
  of processor cycles. Synthesizing instances does not seem to be an issue.
  -/
  

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingEquiv.symm (quotQuotEquivComm I J) = quotQuotEquivComm J I

Next tactic:
change (((quotQuotEquivQuotSup I J).trans (quotEquivOfEq (sup_comm))).trans
    (quotQuotEquivQuotSup J I).symm).symm =
      ((quotQuotEquivQuotSup J I).trans (quotEquivOfEq (sup_comm))).trans
        (quotQuotEquivQuotSup I J).symm
@[simp]
theorem quotQuotEquivComm_symm : (quotQuotEquivComm I J).symm = quotQuotEquivComm J I := by
  /-  Porting note: this proof used to just be rfl but currently rfl opens up a bottomless pit
  of processor cycles. Synthesizing instances does not seem to be an issue.
  -/
  change (((quotQuotEquivQuotSup I J).trans (quotEquivOfEq (sup_comm))).trans
    (quotQuotEquivQuotSup J I).symm).symm =
      ((quotQuotEquivQuotSup J I).trans (quotEquivOfEq (sup_comm))).trans
        (quotQuotEquivQuotSup I J).symm
  

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
⊢ RingEquiv.symm
      (RingEquiv.trans (RingEquiv.trans (quotQuotEquivQuotSup I J) (quotEquivOfEq (_ : I ⊔ J = J ⊔ I)))
        (RingEquiv.symm (quotQuotEquivQuotSup J I))) =
    RingEquiv.trans (RingEquiv.trans (quotQuotEquivQuotSup J I) (quotEquivOfEq (_ : J ⊔ I = I ⊔ J)))
      (RingEquiv.symm (quotQuotEquivQuotSup I J))

Next tactic:
ext r
@[simp]
theorem quotQuotEquivComm_symm : (quotQuotEquivComm I J).symm = quotQuotEquivComm J I := by
  /-  Porting note: this proof used to just be rfl but currently rfl opens up a bottomless pit
  of processor cycles. Synthesizing instances does not seem to be an issue.
  -/
  change (((quotQuotEquivQuotSup I J).trans (quotEquivOfEq (sup_comm))).trans
    (quotQuotEquivQuotSup J I).symm).symm =
      ((quotQuotEquivQuotSup J I).trans (quotEquivOfEq (sup_comm))).trans
        (quotQuotEquivQuotSup I J).symm
  ext r
  

Proof state:
case h
R : Type u
inst✝ : CommRing R
I J : Ideal R
r : (R ⧸ J) ⧸ map (Ideal.Quotient.mk J) I
⊢ (RingEquiv.symm
        (RingEquiv.trans (RingEquiv.trans (quotQuotEquivQuotSup I J) (quotEquivOfEq (_ : I ⊔ J = J ⊔ I)))
          (RingEquiv.symm (quotQuotEquivQuotSup J I))))
      r =
    (RingEquiv.trans (RingEquiv.trans (quotQuotEquivQuotSup J I) (quotEquivOfEq (_ : J ⊔ I = I ⊔ J)))
        (RingEquiv.symm (quotQuotEquivQuotSup I J)))
      r

Next tactic:
dsimp
@[simp]
theorem quotQuotEquivComm_symm : (quotQuotEquivComm I J).symm = quotQuotEquivComm J I := by
  /-  Porting note: this proof used to just be rfl but currently rfl opens up a bottomless pit
  of processor cycles. Synthesizing instances does not seem to be an issue.
  -/
  change (((quotQuotEquivQuotSup I J).trans (quotEquivOfEq (sup_comm))).trans
    (quotQuotEquivQuotSup J I).symm).symm =
      ((quotQuotEquivQuotSup J I).trans (quotEquivOfEq (sup_comm))).trans
        (quotQuotEquivQuotSup I J).symm
  ext r
  dsimp
  

Proof state:
case h
R : Type u
inst✝ : CommRing R
I J : Ideal R
r : (R ⧸ J) ⧸ map (Ideal.Quotient.mk J) I
⊢ (RingEquiv.symm (quotQuotEquivQuotSup I J))
      ((RingEquiv.symm (quotEquivOfEq (_ : I ⊔ J = J ⊔ I)))
        ((RingEquiv.symm (RingEquiv.symm (quotQuotEquivQuotSup J I))) r)) =
    (RingEquiv.symm (quotQuotEquivQuotSup I J)) ((quotEquivOfEq (_ : J ⊔ I = I ⊔ J)) ((quotQuotEquivQuotSup J I) r))

Next tactic:
rfl
theorem quotQuotEquivQuotOfLE_comp_quotQuotMk (h : I ≤ J) :
    RingHom.comp (↑(quotQuotEquivQuotOfLE h)) (quotQuotMk I J) = (Ideal.Quotient.mk J) := by
  

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
h : I ≤ J
⊢ RingHom.comp (↑(quotQuotEquivQuotOfLE h)) (quotQuotMk I J) = Ideal.Quotient.mk J

Next tactic:
ext
theorem quotQuotEquivQuotOfLE_comp_quotQuotMk (h : I ≤ J) :
    RingHom.comp (↑(quotQuotEquivQuotOfLE h)) (quotQuotMk I J) = (Ideal.Quotient.mk J) := by
  ext
  

Proof state:
case a
R : Type u
inst✝ : CommRing R
I J : Ideal R
h : I ≤ J
x✝ : R
⊢ (RingHom.comp (↑(quotQuotEquivQuotOfLE h)) (quotQuotMk I J)) x✝ = (Ideal.Quotient.mk J) x✝

Next tactic:
rfl
theorem quotQuotEquivQuotOfLE_symm_comp_mk (h : I ≤ J) :
    RingHom.comp (↑(quotQuotEquivQuotOfLE h).symm) (Ideal.Quotient.mk J) = quotQuotMk I J := by
  

Proof state:
R : Type u
inst✝ : CommRing R
I J : Ideal R
h : I ≤ J
⊢ RingHom.comp (↑(RingEquiv.symm (quotQuotEquivQuotOfLE h))) (Ideal.Quotient.mk J) = quotQuotMk I J

Next tactic:
ext
theorem quotQuotEquivQuotOfLE_symm_comp_mk (h : I ≤ J) :
    RingHom.comp (↑(quotQuotEquivQuotOfLE h).symm) (Ideal.Quotient.mk J) = quotQuotMk I J := by
  ext
  

Proof state:
case a
R : Type u
inst✝ : CommRing R
I J : Ideal R
h : I ≤ J
x✝ : R
⊢ (RingHom.comp (↑(RingEquiv.symm (quotQuotEquivQuotOfLE h))) (Ideal.Quotient.mk J)) x✝ = (quotQuotMk I J) x✝

Next tactic:
rfl
@[simp]
theorem quotQuotEquivComm_symmₐ : (quotQuotEquivCommₐ R I J).symm = quotQuotEquivCommₐ R J I := by
  -- Porting note: should just be `rfl` but `AlgEquiv.toRingEquiv` and `AlgEquiv.ofRingEquiv`
  -- involve repacking everything in the structure, so Lean ends up unfolding `quotQuotEquivComm`
  -- and timing out.
  

Proof state:
R : Type u
A : Type u_1
inst✝² : CommSemiring R
inst✝¹ : CommRing A
inst✝ : Algebra R A
I J : Ideal A
⊢ AlgEquiv.symm (quotQuotEquivCommₐ R I J) = quotQuotEquivCommₐ R J I

Next tactic:
ext
@[simp]
theorem quotQuotEquivComm_symmₐ : (quotQuotEquivCommₐ R I J).symm = quotQuotEquivCommₐ R J I := by
  -- Porting note: should just be `rfl` but `AlgEquiv.toRingEquiv` and `AlgEquiv.ofRingEquiv`
  -- involve repacking everything in the structure, so Lean ends up unfolding `quotQuotEquivComm`
  -- and timing out.
  ext
  

Proof state:
case h
R : Type u
A : Type u_1
inst✝² : CommSemiring R
inst✝¹ : CommRing A
inst✝ : Algebra R A
I J : Ideal A
a✝ : (A ⧸ J) ⧸ map (Quotient.mkₐ R J) I
⊢ (AlgEquiv.symm (quotQuotEquivCommₐ R I J)) a✝ = (quotQuotEquivCommₐ R J I) a✝

Next tactic:
unfold quotQuotEquivCommₐ
@[simp]
theorem quotQuotEquivComm_symmₐ : (quotQuotEquivCommₐ R I J).symm = quotQuotEquivCommₐ R J I := by
  -- Porting note: should just be `rfl` but `AlgEquiv.toRingEquiv` and `AlgEquiv.ofRingEquiv`
  -- involve repacking everything in the structure, so Lean ends up unfolding `quotQuotEquivComm`
  -- and timing out.
  ext
  unfold quotQuotEquivCommₐ
  

Proof state:
case h
R : Type u
A : Type u_1
inst✝² : CommSemiring R
inst✝¹ : CommRing A
inst✝ : Algebra R A
I J : Ideal A
a✝ : (A ⧸ J) ⧸ map (Quotient.mkₐ R J) I
⊢ (AlgEquiv.symm
        (AlgEquiv.ofRingEquiv
          (_ :
            ∀ (x : R),
              (quotQuotEquivComm I J) ((algebraMap R ((A ⧸ I) ⧸ map (Quotient.mkₐ R I) J)) x) =
                (quotQuotEquivComm I J) ((algebraMap R ((A ⧸ I) ⧸ map (Quotient.mkₐ R I) J)) x))))
      a✝ =
    (AlgEquiv.ofRingEquiv
        (_ :
          ∀ (x : R),
            (quotQuotEquivComm J I) ((algebraMap R ((A ⧸ J) ⧸ map (Quotient.mkₐ R J) I)) x) =
              (quotQuotEquivComm J I) ((algebraMap R ((A ⧸ J) ⧸ map (Quotient.mkₐ R J) I)) x)))
      a✝

Next tactic:
congr
instance : ConcreteCategory SemiRingCat := by
  

Proof state:
⊢ ConcreteCategory SemiRingCat

Next tactic:
dsimp [SemiRingCat]
instance : ConcreteCategory SemiRingCat := by
  dsimp [SemiRingCat]
  

Proof state:
⊢ ConcreteCategory (Bundled Semiring)

Next tactic:
infer_instance
instance forgetReflectIsos : ReflectsIsomorphisms (forget SemiRingCat) where
  reflects {X Y} f _ := by
    

Proof state:
X Y : SemiRingCat
f : X ⟶ Y
x✝ : IsIso ((forget SemiRingCat).map f)
⊢ IsIso f

Next tactic:
let i := asIso ((forget SemiRingCat).map f)
instance forgetReflectIsos : ReflectsIsomorphisms (forget SemiRingCat) where
  reflects {X Y} f _ := by
    let i := asIso ((forget SemiRingCat).map f)
    

Proof state:
X Y : SemiRingCat
f : X ⟶ Y
x✝ : IsIso ((forget SemiRingCat).map f)
i : (forget SemiRingCat).obj X ≅ (forget SemiRingCat).obj Y := asIso ((forget SemiRingCat).map f)
⊢ IsIso f

Next tactic:
let ff : X →+* Y := f
instance forgetReflectIsos : ReflectsIsomorphisms (forget SemiRingCat) where
  reflects {X Y} f _ := by
    let i := asIso ((forget SemiRingCat).map f)
    let ff : X →+* Y := f
    

Proof state:
X Y : SemiRingCat
f : X ⟶ Y
x✝ : IsIso ((forget SemiRingCat).map f)
i : (forget SemiRingCat).obj X ≅ (forget SemiRingCat).obj Y := asIso ((forget SemiRingCat).map f)
ff : ↑X →+* ↑Y := f
⊢ IsIso f

Next tactic:
let e : X ≃+* Y := { ff, i.toEquiv with }
instance forgetReflectIsos : ReflectsIsomorphisms (forget SemiRingCat) where
  reflects {X Y} f _ := by
    let i := asIso ((forget SemiRingCat).map f)
    let ff : X →+* Y := f
    let e : X ≃+* Y := { ff, i.toEquiv with }
    

Proof state:
X Y : SemiRingCat
f : X ⟶ Y
x✝ : IsIso ((forget SemiRingCat).map f)
i : (forget SemiRingCat).obj X ≅ (forget SemiRingCat).obj Y := asIso ((forget SemiRingCat).map f)
ff : ↑X →+* ↑Y := f
e : ↑X ≃+* ↑Y :=
  let src := i.toEquiv;
  {
    toEquiv :=
      { toFun := ff.toFun, invFun := src.invFun, left_inv := (_ : Function.LeftInverse src.invFun src.toFun),
        right_inv := (_ : Function.RightInverse src.invFun src.toFun) },
    map_mul' := (_ : ∀ (x y : ↑X), OneHom.toFun (↑↑ff) (x * y) = OneHom.toFun (↑↑ff) x * OneHom.toFun (↑↑ff) y),
    map_add' := (_ : ∀ (x y : ↑X), OneHom.toFun (↑↑ff) (x + y) = OneHom.toFun (↑↑ff) x + OneHom.toFun (↑↑ff) y) }
⊢ IsIso f

Next tactic:
exact ⟨(IsIso.of_iso e.toSemiRingCatIso).1⟩
instance : ConcreteCategory RingCat := by
  

Proof state:
⊢ ConcreteCategory RingCat

Next tactic:
dsimp [RingCat]
instance : ConcreteCategory RingCat := by
  dsimp [RingCat]
  

Proof state:
⊢ ConcreteCategory (Bundled Ring)

Next tactic:
infer_instance
instance : ConcreteCategory CommSemiRingCat := by
  

Proof state:
⊢ ConcreteCategory CommSemiRingCat

Next tactic:
dsimp [CommSemiRingCat]
instance : ConcreteCategory CommSemiRingCat := by
  dsimp [CommSemiRingCat]
  

Proof state:
⊢ ConcreteCategory (Bundled CommSemiring)

Next tactic:
infer_instance
/-- The forgetful functor from commutative rings to (multiplicative) commutative monoids. -/
instance hasForgetToCommMonCat : HasForget₂ CommSemiRingCat CommMonCat :=
  HasForget₂.mk' (fun R : CommSemiRingCat => CommMonCat.of R) (fun R => rfl)
    -- Porting note: `(_ := _)` trick
    (fun {R₁ R₂} f => RingHom.toMonoidHom (α := R₁) (β := R₂) f) (by 

Proof state:
⊢ ∀ {X Y : CommSemiRingCat} {f : X ⟶ Y},
    HEq ((forget CommMonCat).map ((fun {R₁ R₂} f => ↑f) f)) ((forget CommSemiRingCat).map f)

Next tactic:
rfl
instance forgetReflectIsos : ReflectsIsomorphisms (forget CommSemiRingCat) where
  reflects {X Y} f _ := by
    

Proof state:
X Y : CommSemiRingCat
f : X ⟶ Y
x✝ : IsIso ((forget CommSemiRingCat).map f)
⊢ IsIso f

Next tactic:
let i := asIso ((forget CommSemiRingCat).map f)