Theorem: CategoryTheory.isCodetecting_op_iff
File: Mathlib/CategoryTheory/Generator.lean

tactic: refine ⟨fun h𝒢 X Y f hf => ?_, fun h𝒢 X Y f hf => ?_⟩
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
⊢ IsCodetecting 𝒢.op ↔ IsDetecting 𝒢
state_after: case refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsCodetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
⊢ IsIso f

case refine_2
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
⊢ IsIso f

tactic: refine (isIso_op_iff _).1 (h𝒢 _ fun G hG h => ?_)
state_before: case refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsCodetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
⊢ IsIso f
state_after: case refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsCodetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : Cᵒᵖ
hG : G ∈ 𝒢.op
h : { unop := Y } ⟶ G
⊢ ∃! h', f.op ≫ h' = h

tactic: obtain ⟨t, ht, ht'⟩ := hf (unop G) (Set.mem_op.1 hG) h.unop
state_before: case refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsCodetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : Cᵒᵖ
hG : G ∈ 𝒢.op
h : { unop := Y } ⟶ G
⊢ ∃! h', f.op ≫ h' = h
state_after: case refine_1.intro.intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsCodetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : Cᵒᵖ
hG : G ∈ 𝒢.op
h : { unop := Y } ⟶ G
t : G.unop ⟶ X
ht : t ≫ f = h.unop
ht' : ∀ (y : G.unop ⟶ X), (fun h' => h' ≫ f = h.unop) y → y = t
⊢ ∃! h', f.op ≫ h' = h

tactic: exact
  ⟨t.op, Quiver.Hom.unop_inj ht, fun y hy => Quiver.Hom.unop_inj (ht' _ (Quiver.Hom.op_inj hy))⟩
state_before: case refine_1.intro.intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsCodetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : Cᵒᵖ
hG : G ∈ 𝒢.op
h : { unop := Y } ⟶ G
t : G.unop ⟶ X
ht : t ≫ f = h.unop
ht' : ∀ (y : G.unop ⟶ X), (fun h' => h' ≫ f = h.unop) y → y = t
⊢ ∃! h', f.op ≫ h' = h
state_after: no goals

tactic: refine (isIso_unop_iff _).1 (h𝒢 _ fun G hG h => ?_)
state_before: case refine_2
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
⊢ IsIso f
state_after: case refine_2
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : C
hG : G ∈ 𝒢
h : G ⟶ X.unop
⊢ ∃! h', h' ≫ f.unop = h

tactic: obtain ⟨t, ht, ht'⟩ := hf (op G) (Set.op_mem_op.2 hG) h.op
state_before: case refine_2
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : C
hG : G ∈ 𝒢
h : G ⟶ X.unop
⊢ ∃! h', h' ≫ f.unop = h
state_after: case refine_2.intro.intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : C
hG : G ∈ 𝒢
h : G ⟶ X.unop
t : Y ⟶ { unop := G }
ht : f ≫ t = h.op
ht' : ∀ (y : Y ⟶ { unop := G }), (fun h' => f ≫ h' = h.op) y → y = t
⊢ ∃! h', h' ≫ f.unop = h

tactic: refine ⟨t.unop, Quiver.Hom.op_inj ht, fun y hy => Quiver.Hom.op_inj (ht' _ ?_)⟩
state_before: case refine_2.intro.intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : C
hG : G ∈ 𝒢
h : G ⟶ X.unop
t : Y ⟶ { unop := G }
ht : f ≫ t = h.op
ht' : ∀ (y : Y ⟶ { unop := G }), (fun h' => f ≫ h' = h.op) y → y = t
⊢ ∃! h', h' ≫ f.unop = h
state_after: case refine_2.intro.intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : C
hG : G ∈ 𝒢
h : G ⟶ X.unop
t : Y ⟶ { unop := G }
ht : f ≫ t = h.op
ht' : ∀ (y : Y ⟶ { unop := G }), (fun h' => f ≫ h' = h.op) y → y = t
y : G ⟶ Y.unop
hy : (fun h' => h' ≫ f.unop = h) y
⊢ (fun h' => f ≫ h' = h.op) y.op

tactic: exact Quiver.Hom.unop_inj (by simpa only using hy)
state_before: case refine_2.intro.intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : C
hG : G ∈ 𝒢
h : G ⟶ X.unop
t : Y ⟶ { unop := G }
ht : f ≫ t = h.op
ht' : ∀ (y : Y ⟶ { unop := G }), (fun h' => f ≫ h' = h.op) y → y = t
y : G ⟶ Y.unop
hy : (fun h' => h' ≫ f.unop = h) y
⊢ (fun h' => f ≫ h' = h.op) y.op
state_after: no goals

tactic: simpa only using hy
state_before: C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : C
hG : G ∈ 𝒢
h : G ⟶ X.unop
t : Y ⟶ { unop := G }
ht : f ≫ t = h.op
ht' : ∀ (y : Y ⟶ { unop := G }), (fun h' => f ≫ h' = h.op) y → y = t
y : G ⟶ Y.unop
hy : (fun h' => h' ≫ f.unop = h) y
⊢ (f ≫ y.op).unop = h.op.unop
state_after: no goals