/-- If `A : S → T.obj B` is a structured arrow for `S : D` and `T : C ⥤ D`, then we can explicitly
    describe the subobjects of `A` as the subobjects `P` of `B` in `C` for which `A.hom` factors
    through the image of `P` under `T`. -/
@[simps!]
def subobjectEquiv [HasLimits C] [PreservesLimits T] (A : StructuredArrow S T) :
    Subobject A ≃o { P : Subobject A.right // ∃ q, q ≫ T.map P.arrow = A.hom } where
  toFun P := ⟨projectSubobject P, projectSubobject_factors P⟩
  invFun P := liftSubobject P.val P.prop.choose_spec
  left_inv P := lift_projectSubobject _ _
  right_inv P := Subtype.ext (by simp only [liftSubobject, homMk_right, projectSubobject_mk,
      Subobject.mk_arrow, Subtype.coe_eta])
  map_rel_iff' := by
    apply Subobject.ind₂
    

Proof state:
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 =>
              { val := projectSubobject P,
                property := (_ : ∃ q, q ≫ T.map (Subobject.arrow (projectSubobject P)) = A.hom) },
            invFun := fun P =>
              liftSubobject ↑P
                (_ :
                  Exists.choose (_ : ∃ q, q ≫ T.map (Subobject.arrow ↑P) = A.hom) ≫ T.map (Subobject.arrow ↑P) = A.hom),
            left_inv :=
              (_ :
                ∀ (P : Subobject A),
                  liftSubobject (projectSubobject P)
                      (_ :
                        Exists.choose
                              (_ :
                                ∃ q,
                                  q ≫
                                      T.map
                                        (Subobject.arrow
                                          ↑((fun P =>
                                                { val := projectSubobject P,
                                                  property :=
                                                    (_ :
                                                      ∃ q, q ≫ T.map (Subobject.arrow (projectSubobject P)) = A.hom) })
                                              P)) =
                                    A.hom) ≫
                            T.map
                              (Subobject.arrow
                                ↑((fun P =>
                                      { val := projectSubobject P,
                                        property :=
                                          (_ : ∃ q, q ≫ T.map (Subobject.arrow (projectSubobject P)) = A.hom) })
                                    P)) =
                          A.hom) =
                    P),
            right_inv :=
              (_ :
                ∀ (P : { P // ∃ q, q ≫ T.map (Subobject.arrow P) = A.hom }),
                  (fun P =>
                        { val := projectSubobject P,
                          property := (_ : ∃ q, q ≫ T.map (Subobject.arrow (projectSubobject P)) = A.hom) })
                      ((fun P =>
                          liftSubobject ↑P
                            (_ :
                              Exists.choose (_ : ∃ q, q ≫ T.map (Subobject.arrow ↑P) = A.hom) ≫
                                  T.map (Subobject.arrow ↑P) =
                                A.hom))
                        P) =
                    P) }
          (Subobject.mk f) ≤
        {
            toFun := fun P =>
              { val := projectSubobject P,
                property := (_ : ∃ q, q ≫ T.map (Subobject.arrow (projectSubobject P)) = A.hom) },
            invFun := fun P =>
              liftSubobject ↑P
                (_ :
                  Exists.choose (_ : ∃ q, q ≫ T.map (Subobject.arrow ↑P) = A.hom) ≫ T.map (Subobject.arrow ↑P) = A.hom),
            left_inv :=
              (_ :
                ∀ (P : Subobject A),
                  liftSubobject (projectSubobject P)
                      (_ :
                        Exists.choose
                              (_ :
                                ∃ q,
                                  q ≫
                                      T.map
                                        (Subobject.arrow
                                          ↑((fun P =>
                                                { val := projectSubobject P,
                                                  property :=
                                                    (_ :
                                                      ∃ q, q ≫ T.map (Subobject.arrow (projectSubobject P)) = A.hom) })
                                              P)) =
                                    A.hom) ≫
                            T.map
                              (Subobject.arrow
                                ↑((fun P =>
                                      { val := projectSubobject P,
                                        property :=
                                          (_ : ∃ q, q ≫ T.map (Subobject.arrow (projectSubobject P)) = A.hom) })
                                    P)) =
                          A.hom) =
                    P),
            right_inv :=
              (_ :
                ∀ (P : { P // ∃ q, q ≫ T.map (Subobject.arrow P) = A.hom }),
                  (fun P =>
                        { val := projectSubobject P,
                          property := (_ : ∃ q, q ≫ T.map (Subobject.arrow (projectSubobject P)) = A.hom) })
                      ((fun P =>
                          liftSubobject ↑P
                            (_ :
                              Exists.choose (_ : ∃ q, q ≫ T.map (Subobject.arrow ↑P) = A.hom) ≫
                                  T.map (Subobject.arrow ↑P) =
                                A.hom))
                        P) =
                    P) }
          (Subobject.mk g) ↔
      Subobject.mk f ≤ Subobject.mk g

Next tactic:
intro P Q f g hf hg