Theorem: CategoryTheory.isDetecting_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
⊢ IsDetecting 𝒢.op ↔ IsCodetecting 𝒢
state_after: case refine_1
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
𝒢 : Set C
h𝒢 : IsDetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = 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𝒢 : IsDetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = 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𝒢 : IsDetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : Cᵒᵖ
hG : G ∈ 𝒢.op
h : G ⟶ { unop := X }
⊢ ∃! h', h' ≫ f.op = 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𝒢 : IsDetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : Cᵒᵖ
hG : G ∈ 𝒢.op
h : G ⟶ { unop := X }
⊢ ∃! h', h' ≫ f.op = 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𝒢 : IsDetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : Cᵒᵖ
hG : G ∈ 𝒢.op
h : G ⟶ { unop := X }
t : Y ⟶ G.unop
ht : f ≫ t = h.unop
ht' : ∀ (y : Y ⟶ G.unop), (fun h' => f ≫ h' = h.unop) y → y = t
⊢ ∃! h', h' ≫ f.op = 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𝒢 : IsDetecting 𝒢.op
X Y : C
f : X ⟶ Y
hf : ∀ G ∈ 𝒢, ∀ (h : X ⟶ G), ∃! h', f ≫ h' = h
G : Cᵒᵖ
hG : G ∈ 𝒢.op
h : G ⟶ { unop := X }
t : Y ⟶ G.unop
ht : f ≫ t = h.unop
ht' : ∀ (y : Y ⟶ G.unop), (fun h' => f ≫ h' = h.unop) y → y = t
⊢ ∃! h', h' ≫ f.op = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : C
hG : G ∈ 𝒢
h : Y.unop ⟶ G
⊢ ∃! h', f.unop ≫ h' = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : C
hG : G ∈ 𝒢
h : Y.unop ⟶ G
⊢ ∃! h', f.unop ≫ h' = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : C
hG : G ∈ 𝒢
h : Y.unop ⟶ G
t : { unop := G } ⟶ X
ht : t ≫ f = h.op
ht' : ∀ (y : { unop := G } ⟶ X), (fun h' => h' ≫ f = h.op) y → y = t
⊢ ∃! h', f.unop ≫ h' = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : C
hG : G ∈ 𝒢
h : Y.unop ⟶ G
t : { unop := G } ⟶ X
ht : t ≫ f = h.op
ht' : ∀ (y : { unop := G } ⟶ X), (fun h' => h' ≫ f = h.op) y → y = t
⊢ ∃! h', f.unop ≫ h' = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : C
hG : G ∈ 𝒢
h : Y.unop ⟶ G
t : { unop := G } ⟶ X
ht : t ≫ f = h.op
ht' : ∀ (y : { unop := G } ⟶ X), (fun h' => h' ≫ f = h.op) y → y = t
y : X.unop ⟶ G
hy : (fun h' => f.unop ≫ h' = h) y
⊢ (fun h' => h' ≫ f = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : C
hG : G ∈ 𝒢
h : Y.unop ⟶ G
t : { unop := G } ⟶ X
ht : t ≫ f = h.op
ht' : ∀ (y : { unop := G } ⟶ X), (fun h' => h' ≫ f = h.op) y → y = t
y : X.unop ⟶ G
hy : (fun h' => f.unop ≫ h' = h) y
⊢ (fun h' => h' ≫ f = 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𝒢 : IsCodetecting 𝒢
X Y : Cᵒᵖ
f : X ⟶ Y
hf : ∀ G ∈ 𝒢.op, ∀ (h : G ⟶ Y), ∃! h', h' ≫ f = h
G : C
hG : G ∈ 𝒢
h : Y.unop ⟶ G
t : { unop := G } ⟶ X
ht : t ≫ f = h.op
ht' : ∀ (y : { unop := G } ⟶ X), (fun h' => h' ≫ f = h.op) y → y = t
y : X.unop ⟶ G
hy : (fun h' => f.unop ≫ h' = h) y
⊢ (y.op ≫ f).unop = h.op.unop
state_after: no goals