-- Mathlib/CategoryTheory/Generator/Basic.lean
theorem isCoseparator_prod (G H : C) [HasBinaryProduct G H] :
    IsCoseparator (G ⨯ H) ↔ IsCoseparating ({G, H} : Set C)

Proof state:
case refine_2
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparating {G, H}
X Y : C
u v : X ⟶ Y
huv : ∀ (h : Y ⟶ G ⨯ H), u ≫ h = v ≫ h
Z : C
hZ : Z ∈ {G, H}
g : Y ⟶ Z
⊢ u ≫ g = v ≫ g

Tactic:
simp only [Set.mem_insert_iff, Set.mem_singleton_iff] at hZ

Result:
case refine_2
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparating {G, H}
X Y : C
u v : X ⟶ Y
huv : ∀ (h : Y ⟶ G ⨯ H), u ≫ h = v ≫ h
Z : C
g : Y ⟶ Z
hZ : Z = G ∨ Z = H
⊢ u ≫ g = v ≫ g

Proof state:
case refine_2.inl
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
H X Y : C
u v : X ⟶ Y
Z : C
g : Y ⟶ Z
inst✝ : HasBinaryProduct Z H
h : IsCoseparating {Z, H}
huv : ∀ (h : Y ⟶ Z ⨯ H), u ≫ h = v ≫ h
⊢ u ≫ g = v ≫ g

Tactic:
simpa using huv (prod.lift g 0) =≫ Limits.prod.fst

Result:
no goals

Proof state:
case refine_2.inr
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G X Y : C
u v : X ⟶ Y
Z : C
g : Y ⟶ Z
inst✝ : HasBinaryProduct G Z
h : IsCoseparating {G, Z}
huv : ∀ (h : Y ⟶ G ⨯ Z), u ≫ h = v ≫ h
⊢ u ≫ g = v ≫ g

Tactic:
simpa using huv (prod.lift 0 g) =≫ Limits.prod.snd

Result:
no goals

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
⊢ IsCoseparator (G ⨯ H) ↔ IsCoseparating {G, H}

Tactic:
refine
  ⟨fun h X Y u v huv => ?_, fun h =>
    (isCoseparator_def _).2 fun X Y u v huv => h _ _ fun Z hZ g => ?_⟩

Result:
case refine_1
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparator (G ⨯ H)
X Y : C
u v : X ⟶ Y
huv : ∀ G_1 ∈ {G, H}, ∀ (h : Y ⟶ G_1), u ≫ h = v ≫ h
⊢ u = v

case refine_2
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparating {G, H}
X Y : C
u v : X ⟶ Y
huv : ∀ (h : Y ⟶ G ⨯ H), u ≫ h = v ≫ h
Z : C
hZ : Z ∈ {G, H}
g : Y ⟶ Z
⊢ u ≫ g = v ≫ g

Proof state:
case refine_1
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparator (G ⨯ H)
X Y : C
u v : X ⟶ Y
huv : ∀ G_1 ∈ {G, H}, ∀ (h : Y ⟶ G_1), u ≫ h = v ≫ h
⊢ u = v

Tactic:
refine h.def _ _ fun g => Limits.prod.hom_ext ?_ ?_

Result:
case refine_1.refine_1
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparator (G ⨯ H)
X Y : C
u v : X ⟶ Y
huv : ∀ G_1 ∈ {G, H}, ∀ (h : Y ⟶ G_1), u ≫ h = v ≫ h
g : Y ⟶ G ⨯ H
⊢ (u ≫ g) ≫ prod.fst = (v ≫ g) ≫ prod.fst

case refine_1.refine_2
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparator (G ⨯ H)
X Y : C
u v : X ⟶ Y
huv : ∀ G_1 ∈ {G, H}, ∀ (h : Y ⟶ G_1), u ≫ h = v ≫ h
g : Y ⟶ G ⨯ H
⊢ (u ≫ g) ≫ prod.snd = (v ≫ g) ≫ prod.snd

Proof state:
case refine_1.refine_1
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparator (G ⨯ H)
X Y : C
u v : X ⟶ Y
huv : ∀ G_1 ∈ {G, H}, ∀ (h : Y ⟶ G_1), u ≫ h = v ≫ h
g : Y ⟶ G ⨯ H
⊢ (u ≫ g) ≫ prod.fst = (v ≫ g) ≫ prod.fst

Tactic:
simpa using huv G (by simp) (g ≫ Limits.prod.fst)

Result:
no goals

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparator (G ⨯ H)
X Y : C
u v : X ⟶ Y
huv : ∀ G_1 ∈ {G, H}, ∀ (h : Y ⟶ G_1), u ≫ h = v ≫ h
g : Y ⟶ G ⨯ H
⊢ G ∈ {G, H}

Tactic:
simp

Result:
no goals

Proof state:
case refine_2
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparating {G, H}
X Y : C
u v : X ⟶ Y
huv : ∀ (h : Y ⟶ G ⨯ H), u ≫ h = v ≫ h
Z : C
g : Y ⟶ Z
hZ : Z = G ∨ Z = H
⊢ u ≫ g = v ≫ g

Tactic:
rcases hZ with (rfl | rfl)

Result:
case refine_2.inl
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
H X Y : C
u v : X ⟶ Y
Z : C
g : Y ⟶ Z
inst✝ : HasBinaryProduct Z H
h : IsCoseparating {Z, H}
huv : ∀ (h : Y ⟶ Z ⨯ H), u ≫ h = v ≫ h
⊢ u ≫ g = v ≫ g

case refine_2.inr
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G X Y : C
u v : X ⟶ Y
Z : C
g : Y ⟶ Z
inst✝ : HasBinaryProduct G Z
h : IsCoseparating {G, Z}
huv : ∀ (h : Y ⟶ G ⨯ Z), u ≫ h = v ≫ h
⊢ u ≫ g = v ≫ g

Proof state:
case refine_1.refine_2
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparator (G ⨯ H)
X Y : C
u v : X ⟶ Y
huv : ∀ G_1 ∈ {G, H}, ∀ (h : Y ⟶ G_1), u ≫ h = v ≫ h
g : Y ⟶ G ⨯ H
⊢ (u ≫ g) ≫ prod.snd = (v ≫ g) ≫ prod.snd

Tactic:
simpa using huv H (by simp) (g ≫ Limits.prod.snd)

Result:
no goals

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : HasZeroMorphisms C
G H : C
inst✝ : HasBinaryProduct G H
h : IsCoseparator (G ⨯ H)
X Y : C
u v : X ⟶ Y
huv : ∀ G_1 ∈ {G, H}, ∀ (h : Y ⟶ G_1), u ≫ h = v ≫ h
g : Y ⟶ G ⨯ H
⊢ H ∈ {G, H}

Tactic:
simp

Result:
no goals