l3lab/ntp-mathlib huggingface dataset:
/-- The stalk map of a restriction of a morphism is isomorphic to the stalk map of the original map.
-/
def morphismRestrictStalkMap {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (x) :
    Arrow.mk (PresheafedSpace.stalkMap (f ∣_ U).1 x) ≅
      Arrow.mk (PresheafedSpace.stalkMap f.1 x.1) := by
  fapply Arrow.isoMk'
  · refine' Y.restrictStalkIso U.openEmbedding ((f ∣_ U).1.1 x) ≪≫ TopCat.Presheaf.stalkCongr _ _
    apply Inseparable.of_eq
    exact morphismRestrict_base_coe f U x
  · exact X.restrictStalkIso (Opens.openEmbedding _) _
  · apply TopCat.Presheaf.stalk_hom_ext
    intro V hxV
    change ↑(f ⁻¹ᵁ U) at x
    

Proof state:
case h.ih
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
x : ↥(f⁻¹ᵁ U)
hxV : (f ∣_ U).val.base x ∈ V
⊢ TopCat.Presheaf.germ (Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace.presheaf
        { val := (f ∣_ U).val.base x, property := hxV } ≫
      (PresheafedSpace.restrictStalkIso Y.toPresheafedSpace (_ : OpenEmbedding ⇑(Opens.inclusion U))
              ((f ∣_ U).val.base x) ≪≫
            TopCat.Presheaf.stalkCongr Y.presheaf
              (_ : Inseparable ((Opens.inclusion U) ((f ∣_ U).val.base x)) (f.val.base ↑x))).hom ≫
        PresheafedSpace.stalkMap f.val ↑x =
    TopCat.Presheaf.germ (Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace.presheaf
        { val := (f ∣_ U).val.base x, property := hxV } ≫
      PresheafedSpace.stalkMap (f ∣_ U).val x ≫
        (PresheafedSpace.restrictStalkIso X.toPresheafedSpace (_ : OpenEmbedding ⇑(Opens.inclusion (f⁻¹ᵁ U))) x).hom

Next tactic:
simp only [Scheme.restrict_presheaf_obj, unop_op, Opens.coe_inclusion, Iso.trans_hom,
      TopCat.Presheaf.stalkCongr_hom, Category.assoc, Scheme.restrict_toPresheafedSpace]
/-- The stalk map of a restriction of a morphism is isomorphic to the stalk map of the original map.
-/
def morphismRestrictStalkMap {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (x) :
    Arrow.mk (PresheafedSpace.stalkMap (f ∣_ U).1 x) ≅
      Arrow.mk (PresheafedSpace.stalkMap f.1 x.1) := by
  fapply Arrow.isoMk'
  · refine' Y.restrictStalkIso U.openEmbedding ((f ∣_ U).1.1 x) ≪≫ TopCat.Presheaf.stalkCongr _ _
    apply Inseparable.of_eq
    exact morphismRestrict_base_coe f U x
  · exact X.restrictStalkIso (Opens.openEmbedding _) _
  · apply TopCat.Presheaf.stalk_hom_ext
    intro V hxV
    change ↑(f ⁻¹ᵁ U) at x
    simp only [Scheme.restrict_presheaf_obj, unop_op, Opens.coe_inclusion, Iso.trans_hom,
      TopCat.Presheaf.stalkCongr_hom, Category.assoc, Scheme.restrict_toPresheafedSpace]
    

Proof state:
case h.ih
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
x : ↥(f⁻¹ᵁ U)
hxV : (f ∣_ U).val.base x ∈ V
⊢ TopCat.Presheaf.germ (PresheafedSpace.restrict Y.toPresheafedSpace (_ : OpenEmbedding ⇑(Opens.inclusion U))).presheaf
        { val := (f ∣_ U).val.base x, property := hxV } ≫
      (PresheafedSpace.restrictStalkIso Y.toPresheafedSpace (_ : OpenEmbedding ⇑(Opens.inclusion U))
            ((f ∣_ U).val.base x)).hom ≫
        TopCat.Presheaf.stalkSpecializes Y.presheaf
            (_ : nhds (f.val.base ↑x) ≤ nhds ((Opens.inclusion U) ((f ∣_ U).val.base x))) ≫
          PresheafedSpace.stalkMap f.val ↑x =
    TopCat.Presheaf.germ
        (PresheafedSpace.restrict Y.toPresheafedSpace (_ : OpenEmbedding ⇑(Opens.inclusion U))).presheaf
        { val := (f ∣_ U).val.base x, property := hxV } ≫
      PresheafedSpace.stalkMap (f ∣_ U).val x ≫
        (PresheafedSpace.restrictStalkIso X.toPresheafedSpace (_ : OpenEmbedding ⇑(Opens.inclusion (f⁻¹ᵁ U))) x).hom

Next tactic:
rw [PresheafedSpace.restrictStalkIso_hom_eq_germ_assoc,
      TopCat.Presheaf.germ_stalkSpecializes'_assoc,
      PresheafedSpace.stalkMap_germ'_assoc, PresheafedSpace.stalkMap_germ', morphismRestrict_c_app,
      PresheafedSpace.restrictStalkIso_hom_eq_germ, Category.assoc, TopCat.Presheaf.germ_res]
/-- The stalk map of a restriction of a morphism is isomorphic to the stalk map of the original map.
-/
def morphismRestrictStalkMap {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) (x) :
    Arrow.mk (PresheafedSpace.stalkMap (f ∣_ U).1 x) ≅
      Arrow.mk (PresheafedSpace.stalkMap f.1 x.1) := by
  fapply Arrow.isoMk'
  · refine' Y.restrictStalkIso U.openEmbedding ((f ∣_ U).1.1 x) ≪≫ TopCat.Presheaf.stalkCongr _ _
    apply Inseparable.of_eq
    exact morphismRestrict_base_coe f U x
  · exact X.restrictStalkIso (Opens.openEmbedding _) _
  · apply TopCat.Presheaf.stalk_hom_ext
    intro V hxV
    change ↑(f ⁻¹ᵁ U) at x
    simp only [Scheme.restrict_presheaf_obj, unop_op, Opens.coe_inclusion, Iso.trans_hom,
      TopCat.Presheaf.stalkCongr_hom, Category.assoc, Scheme.restrict_toPresheafedSpace]
    rw [PresheafedSpace.restrictStalkIso_hom_eq_germ_assoc,
      TopCat.Presheaf.germ_stalkSpecializes'_assoc,
      PresheafedSpace.stalkMap_germ'_assoc, PresheafedSpace.stalkMap_germ', morphismRestrict_c_app,
      PresheafedSpace.restrictStalkIso_hom_eq_germ, Category.assoc, TopCat.Presheaf.germ_res]
    

Proof state:
case h.ih
C : Type u
inst✝ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
V : Opens ↑↑(Y ∣_ᵤ U).toLocallyRingedSpace.toSheafedSpace.toPresheafedSpace
x : ↥(f⁻¹ᵁ U)
hxV : (f ∣_ U).val.base x ∈ V
⊢ f.val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V)) ≫
      TopCat.Presheaf.germ X.presheaf
        { val := ↑x,
          property := (_ : f.val.base ↑x ∈ ↑((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V)) } =
    f.val.c.app (op ((IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V)) ≫
      TopCat.Presheaf.germ X.presheaf
        ((fun x =>
            { val := ↑x,
              property := (_ : ↑x ∈ ↑(f⁻¹ᵁ (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion U))).obj V)) })
          { val := (Opens.inclusion (f⁻¹ᵁ U)) x,
            property :=
              (_ :
                (Opens.inclusion (f⁻¹ᵁ U)) x ∈
                  (IsOpenMap.functor (_ : IsOpenMap ⇑(Opens.inclusion (f⁻¹ᵁ U)))).obj
                    ((Opens.map (f ∣_ U).val.base).obj V)) })

Next tactic:
rfl
instance {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) [IsOpenImmersion f] :
    IsOpenImmersion (f ∣_ U) := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
inst✝ : IsOpenImmersion f
⊢ IsOpenImmersion (f ∣_ U)

Next tactic:
delta morphismRestrict
instance {X Y : Scheme} (f : X ⟶ Y) (U : Opens Y) [IsOpenImmersion f] :
    IsOpenImmersion (f ∣_ U) := by
  delta morphismRestrict
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y : Scheme
f : X ⟶ Y
U : Opens ↑↑Y.toPresheafedSpace
inst✝ : IsOpenImmersion f
⊢ IsOpenImmersion ((pullbackRestrictIsoRestrict f U).inv ≫ pullback.snd)

Next tactic:
exact PresheafedSpace.IsOpenImmersion.comp _ _
@[to_additive]
theorem mulDysonETransform.subset :
    (mulDysonETransform e x).1 * (mulDysonETransform e x).2 ⊆ x.1 * x.2 := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ (mulDysonETransform e x).1 * (mulDysonETransform e x).2 ⊆ x.1 * x.2

Next tactic:
refine' union_mul_inter_subset_union.trans (union_subset Subset.rfl _)
@[to_additive]
theorem mulDysonETransform.subset :
    (mulDysonETransform e x).1 * (mulDysonETransform e x).2 ⊆ x.1 * x.2 := by
  refine' union_mul_inter_subset_union.trans (union_subset Subset.rfl _)
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ e • x.2 * e⁻¹ • x.1 ⊆ x.1 * x.2

Next tactic:
rw [mul_smul_comm, smul_mul_assoc, inv_smul_smul, mul_comm]
@[to_additive]
theorem mulDysonETransform.card :
    (mulDysonETransform e x).1.card + (mulDysonETransform e x).2.card = x.1.card + x.2.card := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ Finset.card (mulDysonETransform e x).1 + Finset.card (mulDysonETransform e x).2 = Finset.card x.1 + Finset.card x.2

Next tactic:
dsimp
@[to_additive]
theorem mulDysonETransform.card :
    (mulDysonETransform e x).1.card + (mulDysonETransform e x).2.card = x.1.card + x.2.card := by
  dsimp
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ Finset.card (x.1 ∪ e • x.2) + Finset.card (x.2 ∩ e⁻¹ • x.1) = Finset.card x.1 + Finset.card x.2

Next tactic:
rw [← card_smul_finset e (_ ∩ _), smul_finset_inter, smul_inv_smul, inter_comm,
    card_union_add_card_inter, card_smul_finset]
@[to_additive (attr := simp)]
theorem mulDysonETransform_idem :
    mulDysonETransform e (mulDysonETransform e x) = mulDysonETransform e x := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ mulDysonETransform e (mulDysonETransform e x) = mulDysonETransform e x

Next tactic:
ext : 1
@[to_additive (attr := simp)]
theorem mulDysonETransform_idem :
    mulDysonETransform e (mulDysonETransform e x) = mulDysonETransform e x := by
  ext : 1 <;> 

Proof state:
case a
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ (mulDysonETransform e (mulDysonETransform e x)).1 = (mulDysonETransform e x).1

Next tactic:
dsimp
@[to_additive (attr := simp)]
theorem mulDysonETransform_idem :
    mulDysonETransform e (mulDysonETransform e x) = mulDysonETransform e x := by
  ext : 1 <;> 

Proof state:
case a
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ (mulDysonETransform e (mulDysonETransform e x)).2 = (mulDysonETransform e x).2

Next tactic:
dsimp
@[to_additive (attr := simp)]
theorem mulDysonETransform_idem :
    mulDysonETransform e (mulDysonETransform e x) = mulDysonETransform e x := by
  ext : 1 <;> dsimp
  · 

Proof state:
case a
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ x.1 ∪ e • x.2 ∪ e • (x.2 ∩ e⁻¹ • x.1) = x.1 ∪ e • x.2

Next tactic:
rw [smul_finset_inter, smul_inv_smul, inter_comm, union_eq_left]
@[to_additive (attr := simp)]
theorem mulDysonETransform_idem :
    mulDysonETransform e (mulDysonETransform e x) = mulDysonETransform e x := by
  ext : 1 <;> dsimp
  · rw [smul_finset_inter, smul_inv_smul, inter_comm, union_eq_left]
    

Proof state:
case a
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ x.1 ∩ e • x.2 ⊆ x.1 ∪ e • x.2

Next tactic:
exact inter_subset_union
@[to_additive (attr := simp)]
theorem mulDysonETransform_idem :
    mulDysonETransform e (mulDysonETransform e x) = mulDysonETransform e x := by
  ext : 1 <;> dsimp
  · rw [smul_finset_inter, smul_inv_smul, inter_comm, union_eq_left]
    exact inter_subset_union
  · 

Proof state:
case a
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ x.2 ∩ e⁻¹ • x.1 ∩ e⁻¹ • (x.1 ∪ e • x.2) = x.2 ∩ e⁻¹ • x.1

Next tactic:
rw [smul_finset_union, inv_smul_smul, union_comm, inter_eq_left]
@[to_additive (attr := simp)]
theorem mulDysonETransform_idem :
    mulDysonETransform e (mulDysonETransform e x) = mulDysonETransform e x := by
  ext : 1 <;> dsimp
  · rw [smul_finset_inter, smul_inv_smul, inter_comm, union_eq_left]
    exact inter_subset_union
  · rw [smul_finset_union, inv_smul_smul, union_comm, inter_eq_left]
    

Proof state:
case a
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ x.2 ∩ e⁻¹ • x.1 ⊆ x.2 ∪ e⁻¹ • x.1

Next tactic:
exact inter_subset_union
@[to_additive]
theorem mulDysonETransform.smul_finset_snd_subset_fst :
    e • (mulDysonETransform e x).2 ⊆ (mulDysonETransform e x).1 := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ e • (mulDysonETransform e x).2 ⊆ (mulDysonETransform e x).1

Next tactic:
dsimp
@[to_additive]
theorem mulDysonETransform.smul_finset_snd_subset_fst :
    e • (mulDysonETransform e x).2 ⊆ (mulDysonETransform e x).1 := by
  dsimp
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ e • (x.2 ∩ e⁻¹ • x.1) ⊆ x.1 ∪ e • x.2

Next tactic:
rw [smul_finset_inter, smul_inv_smul, inter_comm]
@[to_additive]
theorem mulDysonETransform.smul_finset_snd_subset_fst :
    e • (mulDysonETransform e x).2 ⊆ (mulDysonETransform e x).1 := by
  dsimp
  rw [smul_finset_inter, smul_inv_smul, inter_comm]
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ x.1 ∩ e • x.2 ⊆ x.1 ∪ e • x.2

Next tactic:
exact inter_subset_union
@[to_additive (attr := simp)]
theorem mulETransformLeft_one : mulETransformLeft 1 x = x := by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ mulETransformLeft 1 x = x

Next tactic:
simp [mulETransformLeft]
@[to_additive (attr := simp)]
theorem mulETransformRight_one : mulETransformRight 1 x = x := by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ mulETransformRight 1 x = x

Next tactic:
simp [mulETransformRight]
@[to_additive]
theorem mulETransformLeft.fst_mul_snd_subset :
    (mulETransformLeft e x).1 * (mulETransformLeft e x).2 ⊆ x.1 * x.2 := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ (mulETransformLeft e x).1 * (mulETransformLeft e x).2 ⊆ x.1 * x.2

Next tactic:
refine' inter_mul_union_subset_union.trans (union_subset Subset.rfl _)
@[to_additive]
theorem mulETransformLeft.fst_mul_snd_subset :
    (mulETransformLeft e x).1 * (mulETransformLeft e x).2 ⊆ x.1 * x.2 := by
  refine' inter_mul_union_subset_union.trans (union_subset Subset.rfl _)
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ op e • x.1 * e⁻¹ • x.2 ⊆ x.1 * x.2

Next tactic:
rw [op_smul_finset_mul_eq_mul_smul_finset, smul_inv_smul]
@[to_additive]
theorem mulETransformRight.fst_mul_snd_subset :
    (mulETransformRight e x).1 * (mulETransformRight e x).2 ⊆ x.1 * x.2 := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ (mulETransformRight e x).1 * (mulETransformRight e x).2 ⊆ x.1 * x.2

Next tactic:
refine' union_mul_inter_subset_union.trans (union_subset Subset.rfl _)
@[to_additive]
theorem mulETransformRight.fst_mul_snd_subset :
    (mulETransformRight e x).1 * (mulETransformRight e x).2 ⊆ x.1 * x.2 := by
  refine' union_mul_inter_subset_union.trans (union_subset Subset.rfl _)
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ op e • x.1 * e⁻¹ • x.2 ⊆ x.1 * x.2

Next tactic:
rw [op_smul_finset_mul_eq_mul_smul_finset, smul_inv_smul]
@[to_additive]
theorem mulETransformLeft.card :
    (mulETransformLeft e x).1.card + (mulETransformRight e x).1.card = 2 * x.1.card :=
  (card_inter_add_card_union _ _).trans <| by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ Finset.card x.1 + Finset.card (op e • x.1) = 2 * Finset.card x.1

Next tactic:
rw [card_smul_finset, two_mul]
@[to_additive]
theorem mulETransformRight.card :
    (mulETransformLeft e x).2.card + (mulETransformRight e x).2.card = 2 * x.2.card :=
  (card_union_add_card_inter _ _).trans <| by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ Finset.card x.2 + Finset.card (e⁻¹ • x.2) = 2 * Finset.card x.2

Next tactic:
rw [card_smul_finset, two_mul]
/-- This statement is meant to be combined with `le_or_lt_of_add_le_add` and similar lemmas. -/
@[to_additive AddETransform.card "This statement is meant to be combined with
`le_or_lt_of_add_le_add` and similar lemmas."]
protected theorem MulETransform.card :
    (mulETransformLeft e x).1.card + (mulETransformLeft e x).2.card +
        ((mulETransformRight e x).1.card + (mulETransformRight e x).2.card) =
      x.1.card + x.2.card + (x.1.card + x.2.card) := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Group α
e : α
x : Finset α × Finset α
⊢ card (mulETransformLeft e x).1 + card (mulETransformLeft e x).2 +
      (card (mulETransformRight e x).1 + card (mulETransformRight e x).2) =
    card x.1 + card x.2 + (card x.1 + card x.2)

Next tactic:
rw [add_add_add_comm, mulETransformLeft.card, mulETransformRight.card, ← mul_add, two_mul]
@[to_additive (attr := simp)]
theorem mulETransformLeft_inv : mulETransformLeft e⁻¹ x = (mulETransformRight e x.swap).swap := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ mulETransformLeft e⁻¹ x = Prod.swap (mulETransformRight e (Prod.swap x))

Next tactic:
simp [-op_inv, op_smul_eq_smul, mulETransformLeft, mulETransformRight]
@[to_additive (attr := simp)]
theorem mulETransformRight_inv : mulETransformRight e⁻¹ x = (mulETransformLeft e x.swap).swap := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : CommGroup α
e : α
x : Finset α × Finset α
⊢ mulETransformRight e⁻¹ x = Prod.swap (mulETransformLeft e (Prod.swap x))

Next tactic:
simp [-op_inv, op_smul_eq_smul, mulETransformLeft, mulETransformRight]
theorem injective_iff_preservesEpimorphisms_preadditiveYoneda_obj (J : C) :
    Injective J ↔ (preadditiveYoneda.obj J).PreservesEpimorphisms := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
⊢ Injective J ↔ Functor.PreservesEpimorphisms (preadditiveYoneda.obj J)

Next tactic:
rw [injective_iff_preservesEpimorphisms_yoneda_obj]
theorem injective_iff_preservesEpimorphisms_preadditiveYoneda_obj (J : C) :
    Injective J ↔ (preadditiveYoneda.obj J).PreservesEpimorphisms := by
  rw [injective_iff_preservesEpimorphisms_yoneda_obj]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
⊢ Functor.PreservesEpimorphisms (yoneda.obj J) ↔ Functor.PreservesEpimorphisms (preadditiveYoneda.obj J)

Next tactic:
refine'
    ⟨fun h : (preadditiveYoneda.obj J ⋙ (forget AddCommGroupCat)).PreservesEpimorphisms => _, _⟩
theorem injective_iff_preservesEpimorphisms_preadditiveYoneda_obj (J : C) :
    Injective J ↔ (preadditiveYoneda.obj J).PreservesEpimorphisms := by
  rw [injective_iff_preservesEpimorphisms_yoneda_obj]
  refine'
    ⟨fun h : (preadditiveYoneda.obj J ⋙ (forget AddCommGroupCat)).PreservesEpimorphisms => _, _⟩
  · 

Proof state:
case refine'_1
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
h : Functor.PreservesEpimorphisms (preadditiveYoneda.obj J ⋙ forget AddCommGroupCat)
⊢ Functor.PreservesEpimorphisms (preadditiveYoneda.obj J)

Next tactic:
exact
      Functor.preservesEpimorphisms_of_preserves_of_reflects (preadditiveYoneda.obj J) (forget _)
theorem injective_iff_preservesEpimorphisms_preadditiveYoneda_obj (J : C) :
    Injective J ↔ (preadditiveYoneda.obj J).PreservesEpimorphisms := by
  rw [injective_iff_preservesEpimorphisms_yoneda_obj]
  refine'
    ⟨fun h : (preadditiveYoneda.obj J ⋙ (forget AddCommGroupCat)).PreservesEpimorphisms => _, _⟩
  · exact
      Functor.preservesEpimorphisms_of_preserves_of_reflects (preadditiveYoneda.obj J) (forget _)
  · 

Proof state:
case refine'_2
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
⊢ Functor.PreservesEpimorphisms (preadditiveYoneda.obj J) → Functor.PreservesEpimorphisms (yoneda.obj J)

Next tactic:
intro
theorem injective_iff_preservesEpimorphisms_preadditiveYoneda_obj (J : C) :
    Injective J ↔ (preadditiveYoneda.obj J).PreservesEpimorphisms := by
  rw [injective_iff_preservesEpimorphisms_yoneda_obj]
  refine'
    ⟨fun h : (preadditiveYoneda.obj J ⋙ (forget AddCommGroupCat)).PreservesEpimorphisms => _, _⟩
  · exact
      Functor.preservesEpimorphisms_of_preserves_of_reflects (preadditiveYoneda.obj J) (forget _)
  · intro
    

Proof state:
case refine'_2
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
a✝ : Functor.PreservesEpimorphisms (preadditiveYoneda.obj J)
⊢ Functor.PreservesEpimorphisms (yoneda.obj J)

Next tactic:
exact (inferInstance : (preadditiveYoneda.obj J ⋙ forget _).PreservesEpimorphisms)
theorem injective_iff_preservesEpimorphisms_preadditive_yoneda_obj' (J : C) :
    Injective J ↔ (preadditiveYonedaObj J).PreservesEpimorphisms := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
⊢ Injective J ↔ Functor.PreservesEpimorphisms (preadditiveYonedaObj J)

Next tactic:
rw [injective_iff_preservesEpimorphisms_yoneda_obj]
theorem injective_iff_preservesEpimorphisms_preadditive_yoneda_obj' (J : C) :
    Injective J ↔ (preadditiveYonedaObj J).PreservesEpimorphisms := by
  rw [injective_iff_preservesEpimorphisms_yoneda_obj]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
⊢ Functor.PreservesEpimorphisms (yoneda.obj J) ↔ Functor.PreservesEpimorphisms (preadditiveYonedaObj J)

Next tactic:
refine'
    ⟨fun h : (preadditiveYonedaObj J ⋙ (forget <| ModuleCat (End J))).PreservesEpimorphisms => _, _⟩
theorem injective_iff_preservesEpimorphisms_preadditive_yoneda_obj' (J : C) :
    Injective J ↔ (preadditiveYonedaObj J).PreservesEpimorphisms := by
  rw [injective_iff_preservesEpimorphisms_yoneda_obj]
  refine'
    ⟨fun h : (preadditiveYonedaObj J ⋙ (forget <| ModuleCat (End J))).PreservesEpimorphisms => _, _⟩
  · 

Proof state:
case refine'_1
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
h : Functor.PreservesEpimorphisms (preadditiveYonedaObj J ⋙ forget (ModuleCat (End J)))
⊢ Functor.PreservesEpimorphisms (preadditiveYonedaObj J)

Next tactic:
exact
      Functor.preservesEpimorphisms_of_preserves_of_reflects (preadditiveYonedaObj J) (forget _)
theorem injective_iff_preservesEpimorphisms_preadditive_yoneda_obj' (J : C) :
    Injective J ↔ (preadditiveYonedaObj J).PreservesEpimorphisms := by
  rw [injective_iff_preservesEpimorphisms_yoneda_obj]
  refine'
    ⟨fun h : (preadditiveYonedaObj J ⋙ (forget <| ModuleCat (End J))).PreservesEpimorphisms => _, _⟩
  · exact
      Functor.preservesEpimorphisms_of_preserves_of_reflects (preadditiveYonedaObj J) (forget _)
  · 

Proof state:
case refine'_2
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
⊢ Functor.PreservesEpimorphisms (preadditiveYonedaObj J) → Functor.PreservesEpimorphisms (yoneda.obj J)

Next tactic:
intro
theorem injective_iff_preservesEpimorphisms_preadditive_yoneda_obj' (J : C) :
    Injective J ↔ (preadditiveYonedaObj J).PreservesEpimorphisms := by
  rw [injective_iff_preservesEpimorphisms_yoneda_obj]
  refine'
    ⟨fun h : (preadditiveYonedaObj J ⋙ (forget <| ModuleCat (End J))).PreservesEpimorphisms => _, _⟩
  · exact
      Functor.preservesEpimorphisms_of_preserves_of_reflects (preadditiveYonedaObj J) (forget _)
  · intro
    

Proof state:
case refine'_2
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Preadditive C
J : C
a✝ : Functor.PreservesEpimorphisms (preadditiveYonedaObj J)
⊢ Functor.PreservesEpimorphisms (yoneda.obj J)

Next tactic:
exact (inferInstance : (preadditiveYonedaObj J ⋙ forget _).PreservesEpimorphisms)
theorem ext : ∀ {z w : ℤ√d}, z = w ↔ z.re = w.re ∧ z.im = w.im
  | ⟨x, y⟩, ⟨x', y'⟩ =>
    ⟨fun h => by 

Proof state:
d x y x' y' : ℤ
h : { re := x, im := y } = { re := x', im := y' }
⊢ { re := x, im := y }.re = { re := x', im := y' }.re ∧ { re := x, im := y }.im = { re := x', im := y' }.im

Next tactic:
injection h
theorem ext : ∀ {z w : ℤ√d}, z = w ↔ z.re = w.re ∧ z.im = w.im
  | ⟨x, y⟩, ⟨x', y'⟩ =>
    ⟨fun h => by injection h; 

Proof state:
d x y x' y' : ℤ
re_eq✝ : x = x'
im_eq✝ : y = y'
⊢ { re := x, im := y }.re = { re := x', im := y' }.re ∧ { re := x, im := y }.im = { re := x', im := y' }.im

Next tactic:
constructor
theorem ext : ∀ {z w : ℤ√d}, z = w ↔ z.re = w.re ∧ z.im = w.im
  | ⟨x, y⟩, ⟨x', y'⟩ =>
    ⟨fun h => by injection h; constructor <;> 

Proof state:
case left
d x y x' y' : ℤ
re_eq✝ : x = x'
im_eq✝ : y = y'
⊢ { re := x, im := y }.re = { re := x', im := y' }.re

Next tactic:
assumption
theorem ext : ∀ {z w : ℤ√d}, z = w ↔ z.re = w.re ∧ z.im = w.im
  | ⟨x, y⟩, ⟨x', y'⟩ =>
    ⟨fun h => by injection h; constructor <;> 

Proof state:
case right
d x y x' y' : ℤ
re_eq✝ : x = x'
im_eq✝ : y = y'
⊢ { re := x, im := y }.im = { re := x', im := y' }.im

Next tactic:
assumption