/-- 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₂
    intro P Q f g hf hg
    

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 P Q : StructuredArrow S T
f : P ⟶ A
g : Q ⟶ A
hf : Mono f
hg : 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:
refine' ⟨fun h => Subobject.mk_le_mk_of_comm _ _, fun h => _⟩