/-- If `A : S.obj B ⟶ T` is a costructured arrow for `S : C ⥤ D` and `T : D`, then we can
    explicitly describe the quotients of `A` as the quotients `P` of `B` in `C` for which `A.hom`
    factors through the image of `P` under `S`. -/
def quotientEquiv [HasColimits C] [PreservesColimits S] (A : CostructuredArrow S T) :
    Subobject (op A) ≃o { P : Subobject (op A.left) // ∃ q, S.map P.arrow.unop ≫ q = A.hom } where
  toFun P := ⟨projectQuotient P, projectQuotient_factors P⟩
  invFun P := liftQuotient P.val P.prop.choose_spec
  left_inv P := lift_projectQuotient _ _
  right_inv P := Subtype.ext (by simp only [liftQuotient, Quiver.Hom.unop_op, homMk_left,
      Quiver.Hom.op_unop, projectQuotient_mk, Subobject.mk_arrow])
  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 : C ⥤ D
T : D
inst✝¹ : HasColimits C
inst✝ : PreservesColimits S
A : CostructuredArrow S T
⊢ ∀ ⦃A_1 B : (CostructuredArrow S T)ᵒᵖ⦄ (f : A_1 ⟶ op A) (g : B ⟶ op A) [inst : Mono f] [inst_1 : Mono g],
    {
            toFun := fun P =>
              { val := projectQuotient P,
                property := (_ : ∃ q, S.map (Subobject.arrow (projectQuotient P)).unop ≫ q = A.hom) },
            invFun := fun P =>
              liftQuotient ↑P
                (_ :
                  S.map (Subobject.arrow ↑P).unop ≫
                      Exists.choose (_ : ∃ q, S.map (Subobject.arrow ↑P).unop ≫ q = A.hom) =
                    A.hom),
            left_inv :=
              (_ :
                ∀ (P : Subobject (op A)),
                  liftQuotient (projectQuotient P)
                      (_ :
                        S.map
                              (Subobject.arrow
                                  ↑((fun P =>
                                        { val := projectQuotient P,
                                          property :=
                                            (_ : ∃ q, S.map (Subobject.arrow (projectQuotient P)).unop ≫ q = A.hom) })
                                      P)).unop ≫
                            Exists.choose
                              (_ :
                                ∃ q,
                                  S.map
                                        (Subobject.arrow
                                            ↑((fun P =>
                                                  { val := projectQuotient P,
                                                    property :=
                                                      (_ :
                                                        ∃ q,
                                                          S.map (Subobject.arrow (projectQuotient P)).unop ≫ q =
                                                            A.hom) })
                                                P)).unop ≫
                                      q =
                                    A.hom) =
                          A.hom) =
                    P),
            right_inv :=
              (_ :
                ∀ (P : { P // ∃ q, S.map (Subobject.arrow P).unop ≫ q = A.hom }),
                  (fun P =>
                        { val := projectQuotient P,
                          property := (_ : ∃ q, S.map (Subobject.arrow (projectQuotient P)).unop ≫ q = A.hom) })
                      ((fun P =>
                          liftQuotient ↑P
                            (_ :
                              S.map (Subobject.arrow ↑P).unop ≫
                                  Exists.choose (_ : ∃ q, S.map (Subobject.arrow ↑P).unop ≫ q = A.hom) =
                                A.hom))
                        P) =
                    P) }
          (Subobject.mk f) ≤
        {
            toFun := fun P =>
              { val := projectQuotient P,
                property := (_ : ∃ q, S.map (Subobject.arrow (projectQuotient P)).unop ≫ q = A.hom) },
            invFun := fun P =>
              liftQuotient ↑P
                (_ :
                  S.map (Subobject.arrow ↑P).unop ≫
                      Exists.choose (_ : ∃ q, S.map (Subobject.arrow ↑P).unop ≫ q = A.hom) =
                    A.hom),
            left_inv :=
              (_ :
                ∀ (P : Subobject (op A)),
                  liftQuotient (projectQuotient P)
                      (_ :
                        S.map
                              (Subobject.arrow
                                  ↑((fun P =>
                                        { val := projectQuotient P,
                                          property :=
                                            (_ : ∃ q, S.map (Subobject.arrow (projectQuotient P)).unop ≫ q = A.hom) })
                                      P)).unop ≫
                            Exists.choose
                              (_ :
                                ∃ q,
                                  S.map
                                        (Subobject.arrow
                                            ↑((fun P =>
                                                  { val := projectQuotient P,
                                                    property :=
                                                      (_ :
                                                        ∃ q,
                                                          S.map (Subobject.arrow (projectQuotient P)).unop ≫ q =
                                                            A.hom) })
                                                P)).unop ≫
                                      q =
                                    A.hom) =
                          A.hom) =
                    P),
            right_inv :=
              (_ :
                ∀ (P : { P // ∃ q, S.map (Subobject.arrow P).unop ≫ q = A.hom }),
                  (fun P =>
                        { val := projectQuotient P,
                          property := (_ : ∃ q, S.map (Subobject.arrow (projectQuotient P)).unop ≫ q = A.hom) })
                      ((fun P =>
                          liftQuotient ↑P
                            (_ :
                              S.map (Subobject.arrow ↑P).unop ≫
                                  Exists.choose (_ : ∃ q, S.map (Subobject.arrow ↑P).unop ≫ q = A.hom) =
                                A.hom))
                        P) =
                    P) }
          (Subobject.mk g) ↔
      Subobject.mk f ≤ Subobject.mk g

Next tactic:
intro P Q f g hf hg