File: Mathlib/CategoryTheory/Subobject/MonoOver.lean

full_name: CategoryTheory.MonoOver
code: /-- The category of monomorphisms into `X` as a full subcategory of the over category.
This isn't skeletal, so it's not a partial order.

Later we define `Subobject X` as the quotient of this by isomorphisms.
-/
def MonoOver (X : C) 
goal: Type (max u₁ v₁)

full_name: CategoryTheory.instCategoryMonoOver
code: instance (X : C) : Category (MonoOver X) 
goal: CategoryTheory.Category.{v₁, max u₁ v₁} (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.mk'_obj
code: /-- Construct a `MonoOver X`. -/
@[simps]
def mk' {X A : C} (f : A ⟶ X) [hf : Mono f] : MonoOver X 
goal: (CategoryTheory.MonoOver.mk' f).obj = CategoryTheory.Over.mk f

full_name: CategoryTheory.MonoOver.mk'
code: /-- Construct a `MonoOver X`. -/
@[simps]
def mk' {X A : C} (f : A ⟶ X) [hf : Mono f] : MonoOver X 
goal: CategoryTheory.MonoOver X

full_name: CategoryTheory.MonoOver.forget
code: /-- The inclusion from monomorphisms over X to morphisms over X. -/
def forget (X : C) : MonoOver X ⥤ Over X 
goal: CategoryTheory.Functor (CategoryTheory.MonoOver X) (CategoryTheory.Over X)

full_name: CategoryTheory.MonoOver.instCoeOut
code: instance : CoeOut (MonoOver X) C 
goal: CoeOut (CategoryTheory.MonoOver X) C

full_name: CategoryTheory.MonoOver.forget_obj_left
code: @[simp]
theorem forget_obj_left {f} : ((forget X).obj f).left = (f : C) 
goal: ((CategoryTheory.MonoOver.forget X).obj f).left = f.obj.left

full_name: CategoryTheory.MonoOver.mk'_coe'
code: @[simp]
theorem mk'_coe' {X A : C} (f : A ⟶ X) [Mono f] : (mk' f : C) = A 
goal: (CategoryTheory.MonoOver.mk' f).obj.left = A

full_name: CategoryTheory.MonoOver.arrow
code: /-- Convenience notation for the underlying arrow of a monomorphism over X. -/
abbrev arrow (f : MonoOver X) : (f : C) ⟶ X 
goal: f.obj.left ⟶ X

full_name: CategoryTheory.MonoOver.mk'_arrow
code: @[simp]
theorem mk'_arrow {X A : C} (f : A ⟶ X) [Mono f] : (mk' f).arrow = f 
goal: (CategoryTheory.MonoOver.mk' f).arrow = f

full_name: CategoryTheory.MonoOver.forget_obj_hom
code: @[simp]
theorem forget_obj_hom {f} : ((forget X).obj f).hom = f.arrow 
goal: ((CategoryTheory.MonoOver.forget X).obj f).hom = f.arrow

full_name: CategoryTheory.MonoOver.fullyFaithfulForget
code: /-- The forget functor `MonoOver X ⥤ Over X` is fully faithful. -/
def fullyFaithfulForget (X : C) : (forget X).FullyFaithful 
goal: (CategoryTheory.MonoOver.forget X).FullyFaithful

full_name: CategoryTheory.MonoOver.instFullOverForget
code: instance : (forget X).Full 
goal: (CategoryTheory.MonoOver.forget X).Full

full_name: CategoryTheory.MonoOver.instFaithfulOverForget
code: instance : (forget X).Faithful 
goal: (CategoryTheory.MonoOver.forget X).Faithful

full_name: CategoryTheory.MonoOver.mono
code: instance mono (f : MonoOver X) : Mono f.arrow 
goal: CategoryTheory.Mono f.arrow

full_name: CategoryTheory.MonoOver.isThin
code: /-- The category of monomorphisms over X is a thin category,
which makes defining its skeleton easy. -/
instance isThin {X : C} : Quiver.IsThin (MonoOver X) 
goal: Quiver.IsThin (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.w
code: @[reassoc]
theorem w {f g : MonoOver X} (k : f ⟶ g) : k.left ≫ g.arrow = f.arrow 
goal: CategoryTheory.CategoryStruct.comp k.left g.arrow = f.arrow

full_name: CategoryTheory.MonoOver.homMk
code: /-- Convenience constructor for a morphism in monomorphisms over `X`. -/
abbrev homMk {f g : MonoOver X} (h : f.obj.left ⟶ g.obj.left)
    (w : h ≫ g.arrow = f.arrow := by aesop_cat) : f ⟶ g 
goal: f ⟶ g

full_name: CategoryTheory.MonoOver.isoMk
code: /-- Convenience constructor for an isomorphism in monomorphisms over `X`. -/
@[simps]
def isoMk {f g : MonoOver X} (h : f.obj.left ≅ g.obj.left)
    (w : h.hom ≫ g.arrow = f.arrow := by aesop_cat) : f ≅ g 
goal: f ≅ g

full_name: CategoryTheory.MonoOver.isoMk_hom
code: /-- Convenience constructor for an isomorphism in monomorphisms over `X`. -/
@[simps]
def isoMk {f g : MonoOver X} (h : f.obj.left ≅ g.obj.left)
    (w : h.hom ≫ g.arrow = f.arrow := by aesop_cat) : f ≅ g 
goal: (CategoryTheory.MonoOver.isoMk h w).hom = CategoryTheory.MonoOver.homMk h.hom w

full_name: CategoryTheory.MonoOver.isoMk_inv
code: /-- Convenience constructor for an isomorphism in monomorphisms over `X`. -/
@[simps]
def isoMk {f g : MonoOver X} (h : f.obj.left ≅ g.obj.left)
    (w : h.hom ≫ g.arrow = f.arrow := by aesop_cat) : f ≅ g 
goal: (CategoryTheory.MonoOver.isoMk h w).inv = CategoryTheory.MonoOver.homMk h.inv ⋯

full_name: CategoryTheory.MonoOver.mk'ArrowIso
code: /-- If `f : MonoOver X`, then `mk' f.arrow` is of course just `f`, but not definitionally, so we
    package it as an isomorphism. -/
@[simp]
def mk'ArrowIso {X : C} (f : MonoOver X) : mk' f.arrow ≅ f 
goal: CategoryTheory.MonoOver.mk' f.arrow ≅ f

full_name: CategoryTheory.MonoOver.lift_map
code: /-- Lift a functor between over categories to a functor between `MonoOver` categories,
given suitable evidence that morphisms are taken to monomorphisms.
-/
@[simps]
def lift {Y : D} (F : Over Y ⥤ Over X)
    (h : ∀ f : MonoOver Y, Mono (F.obj ((MonoOver.forget Y).obj f)).hom) :
    MonoOver Y ⥤ MonoOver X 
goal: ∀ {X_1 Y_1 : CategoryTheory.MonoOver Y} (k : X_1 ⟶ Y_1),
  (CategoryTheory.MonoOver.lift F h).map k = ((CategoryTheory.MonoOver.forget Y).comp F).map k

full_name: CategoryTheory.MonoOver.lift_obj_obj
code: /-- Lift a functor between over categories to a functor between `MonoOver` categories,
given suitable evidence that morphisms are taken to monomorphisms.
-/
@[simps]
def lift {Y : D} (F : Over Y ⥤ Over X)
    (h : ∀ f : MonoOver Y, Mono (F.obj ((MonoOver.forget Y).obj f)).hom) :
    MonoOver Y ⥤ MonoOver X 
goal: ((CategoryTheory.MonoOver.lift F h).obj f).obj = F.obj ((CategoryTheory.MonoOver.forget Y).obj f)

full_name: CategoryTheory.MonoOver.lift
code: /-- Lift a functor between over categories to a functor between `MonoOver` categories,
given suitable evidence that morphisms are taken to monomorphisms.
-/
@[simps]
def lift {Y : D} (F : Over Y ⥤ Over X)
    (h : ∀ f : MonoOver Y, Mono (F.obj ((MonoOver.forget Y).obj f)).hom) :
    MonoOver Y ⥤ MonoOver X 
goal: CategoryTheory.Functor (CategoryTheory.MonoOver Y) (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.liftIso
code: /-- Isomorphic functors `Over Y ⥤ Over X` lift to isomorphic functors `MonoOver Y ⥤ MonoOver X`.
-/
def liftIso {Y : D} {F₁ F₂ : Over Y ⥤ Over X} (h₁ h₂) (i : F₁ ≅ F₂) : lift F₁ h₁ ≅ lift F₂ h₂ 
goal: CategoryTheory.MonoOver.lift F₁ h₁ ≅ CategoryTheory.MonoOver.lift F₂ h₂

full_name: CategoryTheory.MonoOver.liftComp
code: /-- `MonoOver.lift` commutes with composition of functors. -/
def liftComp {X Z : C} {Y : D} (F : Over X ⥤ Over Y) (G : Over Y ⥤ Over Z) (h₁ h₂) :
    lift F h₁ ⋙ lift G h₂ ≅ lift (F ⋙ G) fun f => h₂ ⟨_, h₁ f⟩ 
goal: (CategoryTheory.MonoOver.lift F h₁).comp (CategoryTheory.MonoOver.lift G h₂) ≅ CategoryTheory.MonoOver.lift (F.comp G) ⋯

full_name: CategoryTheory.MonoOver.liftId
code: /-- `MonoOver.lift` preserves the identity functor. -/
def liftId : (lift (𝟭 (Over X)) fun f => f.2) ≅ 𝟭 _ 
goal: CategoryTheory.MonoOver.lift (CategoryTheory.Functor.id (CategoryTheory.Over X)) ⋯ ≅
  CategoryTheory.Functor.id (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.lift_comm
code: @[simp]
theorem lift_comm (F : Over Y ⥤ Over X)
    (h : ∀ f : MonoOver Y, Mono (F.obj ((MonoOver.forget Y).obj f)).hom) :
    lift F h ⋙ MonoOver.forget X = MonoOver.forget Y ⋙ F 
goal: (CategoryTheory.MonoOver.lift F h).comp (CategoryTheory.MonoOver.forget X) = (CategoryTheory.MonoOver.forget Y).comp F

full_name: CategoryTheory.MonoOver.lift_obj_arrow
code: @[simp]
theorem lift_obj_arrow {Y : D} (F : Over Y ⥤ Over X)
    (h : ∀ f : MonoOver Y, Mono (F.obj ((MonoOver.forget Y).obj f)).hom) (f : MonoOver Y) :
    ((lift F h).obj f).arrow = (F.obj ((forget Y).obj f)).hom 
goal: ((CategoryTheory.MonoOver.lift F h).obj f).arrow = (F.obj ((CategoryTheory.MonoOver.forget Y).obj f)).hom

full_name: CategoryTheory.MonoOver.slice
code: /-- Monomorphisms over an object `f : Over A` in an over category
are equivalent to monomorphisms over the source of `f`.
-/
def slice {A : C} {f : Over A}
    (h₁ : ∀ (g : MonoOver f),
      Mono ((Over.iteratedSliceEquiv f).functor.obj ((forget f).obj g)).hom)
    (h₂ : ∀ (g : MonoOver f.left),
      Mono ((Over.iteratedSliceEquiv f).inverse.obj ((forget f.left).obj g)).hom) :
    MonoOver f ≌ MonoOver f.left 
goal: CategoryTheory.MonoOver f ≌ CategoryTheory.MonoOver f.left

full_name: CategoryTheory.MonoOver.pullback
code: /-- When `C` has pullbacks, a morphism `f : X ⟶ Y` induces a functor `MonoOver Y ⥤ MonoOver X`,
by pulling back a monomorphism along `f`. -/
def pullback (f : X ⟶ Y) : MonoOver Y ⥤ MonoOver X 
goal: CategoryTheory.Functor (CategoryTheory.MonoOver Y) (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.pullbackComp
code: /-- pullback commutes with composition (up to a natural isomorphism) -/
def pullbackComp (f : X ⟶ Y) (g : Y ⟶ Z) : pullback (f ≫ g) ≅ pullback g ⋙ pullback f 
goal: CategoryTheory.MonoOver.pullback (CategoryTheory.CategoryStruct.comp f g) ≅
  (CategoryTheory.MonoOver.pullback g).comp (CategoryTheory.MonoOver.pullback f)

full_name: CategoryTheory.MonoOver.pullbackId
code: /-- pullback preserves the identity (up to a natural isomorphism) -/
def pullbackId : pullback (𝟙 X) ≅ 𝟭 _ 
goal: CategoryTheory.MonoOver.pullback (CategoryTheory.CategoryStruct.id X) ≅
  CategoryTheory.Functor.id (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.pullback_obj_left
code: @[simp]
theorem pullback_obj_left (f : X ⟶ Y) (g : MonoOver Y) :
    ((pullback f).obj g : C) = Limits.pullback g.arrow f 
goal: ((CategoryTheory.MonoOver.pullback f).obj g).obj.left = CategoryTheory.Limits.pullback g.arrow f

full_name: CategoryTheory.MonoOver.pullback_obj_arrow
code: @[simp]
theorem pullback_obj_arrow (f : X ⟶ Y) (g : MonoOver Y) :
    ((pullback f).obj g).arrow = pullback.snd _ _ 
goal: ((CategoryTheory.MonoOver.pullback f).obj g).arrow =
  CategoryTheory.Limits.pullback.snd ((CategoryTheory.MonoOver.forget Y).obj g).hom f

full_name: CategoryTheory.MonoOver.map
code: /-- We can map monomorphisms over `X` to monomorphisms over `Y`
by post-composition with a monomorphism `f : X ⟶ Y`.
-/
def map (f : X ⟶ Y) [Mono f] : MonoOver X ⥤ MonoOver Y 
goal: CategoryTheory.Functor (CategoryTheory.MonoOver X) (CategoryTheory.MonoOver Y)

full_name: CategoryTheory.MonoOver.mapComp
code: /-- `MonoOver.map` commutes with composition (up to a natural isomorphism). -/
def mapComp (f : X ⟶ Y) (g : Y ⟶ Z) [Mono f] [Mono g] : map (f ≫ g) ≅ map f ⋙ map g 
goal: CategoryTheory.MonoOver.map (CategoryTheory.CategoryStruct.comp f g) ≅
  (CategoryTheory.MonoOver.map f).comp (CategoryTheory.MonoOver.map g)

full_name: CategoryTheory.MonoOver.mapId
code: /-- `MonoOver.map` preserves the identity (up to a natural isomorphism). -/
def mapId : map (𝟙 X) ≅ 𝟭 _ 
goal: CategoryTheory.MonoOver.map (CategoryTheory.CategoryStruct.id X) ≅ CategoryTheory.Functor.id (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.map_obj_left
code: @[simp]
theorem map_obj_left (f : X ⟶ Y) [Mono f] (g : MonoOver X) : ((map f).obj g : C) = g.obj.left 
goal: ((CategoryTheory.MonoOver.map f).obj g).obj.left = g.obj.left

full_name: CategoryTheory.MonoOver.map_obj_arrow
code: @[simp]
theorem map_obj_arrow (f : X ⟶ Y) [Mono f] (g : MonoOver X) : ((map f).obj g).arrow = g.arrow ≫ f 
goal: ((CategoryTheory.MonoOver.map f).obj g).arrow = CategoryTheory.CategoryStruct.comp g.arrow f

full_name: CategoryTheory.MonoOver.full_map
code: instance full_map (f : X ⟶ Y) [Mono f] : Functor.Full (map f) 
goal: (CategoryTheory.MonoOver.map f).Full

full_name: CategoryTheory.MonoOver.faithful_map
code: instance faithful_map (f : X ⟶ Y) [Mono f] : Functor.Faithful (map f) 
goal: (CategoryTheory.MonoOver.map f).Faithful

full_name: CategoryTheory.MonoOver.mapIso_unitIso
code: /-- Isomorphic objects have equivalent `MonoOver` categories.
-/
@[simps]
def mapIso {A B : C} (e : A ≅ B) : MonoOver A ≌ MonoOver B 
goal: (CategoryTheory.MonoOver.mapIso e).unitIso =
  ((CategoryTheory.MonoOver.mapComp e.hom e.inv).symm ≪≫
      CategoryTheory.eqToIso ⋯ ≪≫ CategoryTheory.MonoOver.mapId A).symm

full_name: CategoryTheory.MonoOver.mapIso_counitIso
code: /-- Isomorphic objects have equivalent `MonoOver` categories.
-/
@[simps]
def mapIso {A B : C} (e : A ≅ B) : MonoOver A ≌ MonoOver B 
goal: (CategoryTheory.MonoOver.mapIso e).counitIso =
  (CategoryTheory.MonoOver.mapComp e.inv e.hom).symm ≪≫ CategoryTheory.eqToIso ⋯ ≪≫ CategoryTheory.MonoOver.mapId B

full_name: CategoryTheory.MonoOver.mapIso_inverse
code: /-- Isomorphic objects have equivalent `MonoOver` categories.
-/
@[simps]
def mapIso {A B : C} (e : A ≅ B) : MonoOver A ≌ MonoOver B 
goal: (CategoryTheory.MonoOver.mapIso e).inverse = CategoryTheory.MonoOver.map e.inv

full_name: CategoryTheory.MonoOver.mapIso_functor
code: /-- Isomorphic objects have equivalent `MonoOver` categories.
-/
@[simps]
def mapIso {A B : C} (e : A ≅ B) : MonoOver A ≌ MonoOver B 
goal: (CategoryTheory.MonoOver.mapIso e).functor = CategoryTheory.MonoOver.map e.hom

full_name: CategoryTheory.MonoOver.mapIso
code: /-- Isomorphic objects have equivalent `MonoOver` categories.
-/
@[simps]
def mapIso {A B : C} (e : A ≅ B) : MonoOver A ≌ MonoOver B 
goal: CategoryTheory.MonoOver A ≌ CategoryTheory.MonoOver B

full_name: CategoryTheory.MonoOver.congr_functor
code: /-- An equivalence of categories `e` between `C` and `D` induces an equivalence between
    `MonoOver X` and `MonoOver (e.functor.obj X)` whenever `X` is an object of `C`. -/
@[simps]
def congr (e : C ≌ D) : MonoOver X ≌ MonoOver (e.functor.obj X) 
goal: (CategoryTheory.MonoOver.congr X e).functor = CategoryTheory.MonoOver.lift (CategoryTheory.Over.post e.functor) ⋯

full_name: CategoryTheory.MonoOver.congr_counitIso
code: /-- An equivalence of categories `e` between `C` and `D` induces an equivalence between
    `MonoOver X` and `MonoOver (e.functor.obj X)` whenever `X` is an object of `C`. -/
@[simps]
def congr (e : C ≌ D) : MonoOver X ≌ MonoOver (e.functor.obj X) 
goal: (CategoryTheory.MonoOver.congr X e).counitIso =
  CategoryTheory.NatIso.ofComponents (fun Y => CategoryTheory.MonoOver.isoMk (e.counitIso.app Y.obj.left) ⋯) ⋯

full_name: CategoryTheory.MonoOver.congr
code: /-- An equivalence of categories `e` between `C` and `D` induces an equivalence between
    `MonoOver X` and `MonoOver (e.functor.obj X)` whenever `X` is an object of `C`. -/
@[simps]
def congr (e : C ≌ D) : MonoOver X ≌ MonoOver (e.functor.obj X) 
goal: CategoryTheory.MonoOver X ≌ CategoryTheory.MonoOver (e.functor.obj X)

full_name: CategoryTheory.MonoOver.congr_unitIso
code: /-- An equivalence of categories `e` between `C` and `D` induces an equivalence between
    `MonoOver X` and `MonoOver (e.functor.obj X)` whenever `X` is an object of `C`. -/
@[simps]
def congr (e : C ≌ D) : MonoOver X ≌ MonoOver (e.functor.obj X) 
goal: (CategoryTheory.MonoOver.congr X e).unitIso =
  CategoryTheory.NatIso.ofComponents (fun Y => CategoryTheory.MonoOver.isoMk (e.unitIso.app Y.obj.left) ⋯) ⋯

full_name: CategoryTheory.MonoOver.congr_inverse
code: /-- An equivalence of categories `e` between `C` and `D` induces an equivalence between
    `MonoOver X` and `MonoOver (e.functor.obj X)` whenever `X` is an object of `C`. -/
@[simps]
def congr (e : C ≌ D) : MonoOver X ≌ MonoOver (e.functor.obj X) 
goal: (CategoryTheory.MonoOver.congr X e).inverse =
  (CategoryTheory.MonoOver.lift (CategoryTheory.Over.post e.inverse) ⋯).comp
    (CategoryTheory.MonoOver.mapIso (e.unitIso.symm.app X)).functor

full_name: CategoryTheory.MonoOver.mapPullbackAdj
code: /-- `map f` is left adjoint to `pullback f` when `f` is a monomorphism -/
def mapPullbackAdj (f : X ⟶ Y) [Mono f] : map f ⊣ pullback f 
goal: CategoryTheory.MonoOver.map f ⊣ CategoryTheory.MonoOver.pullback f

full_name: CategoryTheory.MonoOver.pullbackMapSelf
code: /-- `MonoOver.map f` followed by `MonoOver.pullback f` is the identity. -/
def pullbackMapSelf (f : X ⟶ Y) [Mono f] : map f ⋙ pullback f ≅ 𝟭 _ 
goal: (CategoryTheory.MonoOver.map f).comp (CategoryTheory.MonoOver.pullback f) ≅
  CategoryTheory.Functor.id (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.imageMonoOver
code: /-- The `MonoOver Y` for the image inclusion for a morphism `f : X ⟶ Y`.
-/
def imageMonoOver (f : X ⟶ Y) [HasImage f] : MonoOver Y 
goal: CategoryTheory.MonoOver Y

full_name: CategoryTheory.MonoOver.imageMonoOver_arrow
code: @[simp]
theorem imageMonoOver_arrow (f : X ⟶ Y) [HasImage f] : (imageMonoOver f).arrow = image.ι f 
goal: (CategoryTheory.MonoOver.imageMonoOver f).arrow = CategoryTheory.Limits.image.ι f

full_name: CategoryTheory.MonoOver.image_obj
code: /-- Taking the image of a morphism gives a functor `Over X ⥤ MonoOver X`.
-/
@[simps]
def image : Over X ⥤ MonoOver X 
goal: CategoryTheory.MonoOver.image.obj f = CategoryTheory.MonoOver.imageMonoOver f.hom

full_name: CategoryTheory.MonoOver.image
code: /-- Taking the image of a morphism gives a functor `Over X ⥤ MonoOver X`.
-/
@[simps]
def image : Over X ⥤ MonoOver X 
goal: CategoryTheory.Functor (CategoryTheory.Over X) (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.image_map
code: /-- Taking the image of a morphism gives a functor `Over X ⥤ MonoOver X`.
-/
@[simps]
def image : Over X ⥤ MonoOver X 
goal: CategoryTheory.MonoOver.image.map k =
  (CategoryTheory.MonoOver.forget X).preimage
    (CategoryTheory.Over.homMk
      (CategoryTheory.Limits.image.lift
        (CategoryTheory.Limits.MonoFactorisation.mk (CategoryTheory.Limits.image g.hom)
          (CategoryTheory.Limits.image.ι g.hom)
          (CategoryTheory.CategoryStruct.comp k.left (CategoryTheory.Limits.factorThruImage g.hom)) ⋯))
      ⋯)

full_name: CategoryTheory.MonoOver.imageForgetAdj
code: /-- `MonoOver.image : Over X ⥤ MonoOver X` is left adjoint to
`MonoOver.forget : MonoOver X ⥤ Over X`
-/
def imageForgetAdj : image ⊣ forget X 
goal: CategoryTheory.MonoOver.image ⊣ CategoryTheory.MonoOver.forget X

full_name: CategoryTheory.MonoOver.instIsRightAdjointOverForget
code: instance : (forget X).IsRightAdjoint 
goal: (CategoryTheory.MonoOver.forget X).IsRightAdjoint

full_name: CategoryTheory.MonoOver.reflective
code: instance reflective : Reflective (forget X) 
goal: CategoryTheory.Reflective (CategoryTheory.MonoOver.forget X)

full_name: CategoryTheory.MonoOver.forgetImage
code: /-- Forgetting that a monomorphism over `X` is a monomorphism, then taking its image,
is the identity functor.
-/
def forgetImage : forget X ⋙ image ≅ 𝟭 (MonoOver X) 
goal: (CategoryTheory.MonoOver.forget X).comp CategoryTheory.MonoOver.image ≅
  CategoryTheory.Functor.id (CategoryTheory.MonoOver X)

full_name: CategoryTheory.MonoOver.exists
code: /-- In the case where `f` is not a monomorphism but `C` has images,
we can still take the "forward map" under it, which agrees with `MonoOver.map f`.
-/
def «exists» (f : X ⟶ Y) : MonoOver X ⥤ MonoOver Y 
goal: CategoryTheory.Functor (CategoryTheory.MonoOver X) (CategoryTheory.MonoOver Y)

full_name: CategoryTheory.MonoOver.faithful_exists
code: instance faithful_exists (f : X ⟶ Y) : Functor.Faithful («exists» f) 
goal: (CategoryTheory.MonoOver.exists f).Faithful

full_name: CategoryTheory.MonoOver.existsIsoMap
code: /-- When `f : X ⟶ Y` is a monomorphism, `exists f` agrees with `map f`.
-/
def existsIsoMap (f : X ⟶ Y) [Mono f] : «exists» f ≅ map f 
goal: CategoryTheory.MonoOver.exists f ≅ CategoryTheory.MonoOver.map f

full_name: CategoryTheory.MonoOver.existsPullbackAdj
code: /-- `exists` is adjoint to `pullback` when images exist -/
def existsPullbackAdj (f : X ⟶ Y) [HasPullbacks C] : «exists» f ⊣ pullback f 
goal: CategoryTheory.MonoOver.exists f ⊣ CategoryTheory.MonoOver.pullback f