Theorem: CategoryTheory.StructuredArrow.subobjectEquiv_symm_apply
File: Mathlib/CategoryTheory/Subobject/Comma.lean

Proof steps:
state_before: C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A : StructuredArrow S T
P : { P // ∃ q, q ≫ T.map P.arrow = A.hom }
⊢ ↑((fun P => ⟨projectSubobject P, ⋯⟩) ((fun P => liftSubobject ↑P ⋯) P)) = ↑P
state_after: no goals
tactic: simp only [liftSubobject, homMk_right, projectSubobject_mk,
      Subobject.mk_arrow, Subtype.coe_eta]
state_before: C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A : StructuredArrow S T
⊢ ∀ {a b : Subobject A},
    { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
          a ≤
        { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯,
            right_inv := ⋯ }
          b ↔
      a ≤ b
state_after: case h
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A : StructuredArrow S T
⊢ ∀ ⦃A_1 B : StructuredArrow S T⦄ (f : A_1 ⟶ A) (g : B ⟶ A) [inst : Mono f] [inst_1 : Mono g],
    { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
          (Subobject.mk f) ≤
        { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯,
            right_inv := ⋯ }
          (Subobject.mk g) ↔
      Subobject.mk f ≤ Subobject.mk g
tactic: apply Subobject.ind₂
state_before: case h
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A : StructuredArrow S T
⊢ ∀ ⦃A_1 B : StructuredArrow S T⦄ (f : A_1 ⟶ A) (g : B ⟶ A) [inst : Mono f] [inst_1 : Mono g],
    { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
          (Subobject.mk f) ≤
        { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯,
            right_inv := ⋯ }
          (Subobject.mk g) ↔
      Subobject.mk f ≤ Subobject.mk g
state_after: case h
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A P Q : StructuredArrow S T
f : P ⟶ A
g : Q ⟶ A
hf : Mono f
hg : Mono g
⊢ { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
        (Subobject.mk f) ≤
      { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯,
          right_inv := ⋯ }
        (Subobject.mk g) ↔
    Subobject.mk f ≤ Subobject.mk g
tactic: intro P Q f g hf hg
state_before: case h
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A P Q : StructuredArrow S T
f : P ⟶ A
g : Q ⟶ A
hf : Mono f
hg : Mono g
⊢ { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
        (Subobject.mk f) ≤
      { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯,
          right_inv := ⋯ }
        (Subobject.mk g) ↔
    Subobject.mk f ≤ Subobject.mk g
state_after: case h.refine_1
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A P Q : StructuredArrow S T
f : P ⟶ A
g : Q ⟶ A
hf : Mono f
hg : Mono g
h :
  { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
      (Subobject.mk f) ≤
    { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
      (Subobject.mk g)
⊢ P ⟶ Q

case h.refine_2
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A P Q : StructuredArrow S T
f : P ⟶ A
g : Q ⟶ A
hf : Mono f
hg : Mono g
h :
  { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
      (Subobject.mk f) ≤
    { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
      (Subobject.mk g)
⊢ ?h.refine_1 ≫ g = f

case h.refine_3
C : Type u₁
inst✝³ : Category.{v, u₁} C
D : Type u₂
inst✝² : Category.{v, u₂} D
S : D
T : C ⥤ D
inst✝¹ : HasLimits C
inst✝ : PreservesLimits T
A P Q : StructuredArrow S T
f : P ⟶ A
g : Q ⟶ A
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
      (Subobject.mk f) ≤
    { toFun := fun P => ⟨projectSubobject P, ⋯⟩, invFun := fun P => liftSubobject ↑P ⋯, left_inv := ⋯, right_inv := ⋯ }
      (Subobject.mk g)
tactic: refine ⟨fun h => Subobject.mk_le_mk_of_comm ?_ ?_, fun h => ?_⟩