File: Mathlib/CategoryTheory/Functor/FullyFaithful.lean

full_name: CategoryTheory.Functor.Full.map_surjective
code: /-- A functor `F : C ⥤ D` is full if for each `X Y : C`, `F.map` is surjective.

See <https://stacks.math.columbia.edu/tag/001C>.
-/
class Full (F : C ⥤ D) : Prop where
  map_surjective {X Y : C} : Function.Surjective (F.map (X := X) (Y := Y))
goal: Function.Surjective F.map

full_name: CategoryTheory.Functor.Full
code: /-- A functor `F : C ⥤ D` is full if for each `X Y : C`, `F.map` is surjective.

See <https://stacks.math.columbia.edu/tag/001C>.
-/
class Full (F : C ⥤ D) : Prop where
  map_surjective {X Y : C} : Function.Surjective (F.map (X := X) (Y := Y))
goal: Prop

full_name: CategoryTheory.Functor.Faithful
code: /-- A functor `F : C ⥤ D` is faithful if for each `X Y : C`, `F.map` is injective.

See <https://stacks.math.columbia.edu/tag/001C>.
-/
class Faithful (F : C ⥤ D) : Prop where
  /-- `F.map` is injective for each `X Y : C`. -/
  map_injective : ∀ {X Y : C}, Function.Injective (F.map : (X ⟶ Y) → (F.obj X ⟶ F.obj Y)) := by
    aesop_cat
goal: Prop

full_name: CategoryTheory.Functor.Faithful.map_injective
code: /-- A functor `F : C ⥤ D` is faithful if for each `X Y : C`, `F.map` is injective.

See <https://stacks.math.columbia.edu/tag/001C>.
-/
class Faithful (F : C ⥤ D) : Prop where
  /-- `F.map` is injective for each `X Y : C`. -/
  map_injective : ∀ {X Y : C}, Function.Injective (F.map : (X ⟶ Y) → (F.obj X ⟶ F.obj Y)) := by
    aesop_cat
goal: Function.Injective F.map

full_name: CategoryTheory.Functor.map_injective
code: theorem map_injective (F : C ⥤ D) [Faithful F] :
    Function.Injective <| (F.map : (X ⟶ Y) → (F.obj X ⟶ F.obj Y)) 
goal: Function.Injective F.map

full_name: CategoryTheory.Functor.map_injective_iff
code: lemma map_injective_iff (F : C ⥤ D) [Faithful F] {X Y : C} (f g : X ⟶ Y) :
    F.map f = F.map g ↔ f = g 
goal: F.map f = F.map g ↔ f = g

full_name: CategoryTheory.Functor.mapIso_injective
code: theorem mapIso_injective (F : C ⥤ D) [Faithful F] :
    Function.Injective <| (F.mapIso : (X ≅ Y) → (F.obj X ≅ F.obj Y))  
goal: Function.Injective F.mapIso

full_name: CategoryTheory.Functor.map_surjective
code: theorem map_surjective (F : C ⥤ D) [Full F] :
    Function.Surjective (F.map : (X ⟶ Y) → (F.obj X ⟶ F.obj Y)) 
goal: Function.Surjective F.map

full_name: CategoryTheory.Functor.preimage
code: /-- The choice of a preimage of a morphism under a full functor. -/
noncomputable def preimage (F : C ⥤ D) [Full F] (f : F.obj X ⟶ F.obj Y) : X ⟶ Y 
goal: X ⟶ Y

full_name: CategoryTheory.Functor.map_preimage
code: @[simp]
theorem map_preimage (F : C ⥤ D) [Full F] {X Y : C} (f : F.obj X ⟶ F.obj Y) :
    F.map (preimage F f) = f 
goal: F.map (F.preimage f) = f

full_name: CategoryTheory.Functor.preimage_id
code: @[simp]
theorem preimage_id : F.preimage (𝟙 (F.obj X)) = 𝟙 X 
goal: F.preimage (CategoryTheory.CategoryStruct.id (F.obj X)) = CategoryTheory.CategoryStruct.id X

full_name: CategoryTheory.Functor.preimage_comp
code: @[simp]
theorem preimage_comp (f : F.obj X ⟶ F.obj Y) (g : F.obj Y ⟶ F.obj Z) :
    F.preimage (f ≫ g) = F.preimage f ≫ F.preimage g 
goal: F.preimage (CategoryTheory.CategoryStruct.comp f g) = CategoryTheory.CategoryStruct.comp (F.preimage f) (F.preimage g)

full_name: CategoryTheory.Functor.preimage_map
code: @[simp]
theorem preimage_map (f : X ⟶ Y) : F.preimage (F.map f) = f 
goal: F.preimage (F.map f) = f

full_name: CategoryTheory.Functor.preimageIso_inv
code: /-- If `F : C ⥤ D` is fully faithful, every isomorphism `F.obj X ≅ F.obj Y` has a preimage. -/
@[simps]
noncomputable def preimageIso (f : F.obj X ≅ F.obj Y) :
    X ≅ Y 
goal: (F.preimageIso f).inv = F.preimage f.inv

full_name: CategoryTheory.Functor.preimageIso
code: /-- If `F : C ⥤ D` is fully faithful, every isomorphism `F.obj X ≅ F.obj Y` has a preimage. -/
@[simps]
noncomputable def preimageIso (f : F.obj X ≅ F.obj Y) :
    X ≅ Y 
goal: X ≅ Y

full_name: CategoryTheory.Functor.preimageIso_hom
code: /-- If `F : C ⥤ D` is fully faithful, every isomorphism `F.obj X ≅ F.obj Y` has a preimage. -/
@[simps]
noncomputable def preimageIso (f : F.obj X ≅ F.obj Y) :
    X ≅ Y 
goal: (F.preimageIso f).hom = F.preimage f.hom

full_name: CategoryTheory.Functor.preimageIso_mapIso
code: @[simp]
theorem preimageIso_mapIso (f : X ≅ Y) : F.preimageIso (F.mapIso f) = f 
goal: F.preimageIso (F.mapIso f) = f

full_name: CategoryTheory.Functor.FullyFaithful.map_preimage
code: /-- Structure containing the data of inverse map `(F.obj X ⟶ F.obj Y) ⟶ (X ⟶ Y)` of `F.map`
in order to express that `F` is a fully faithful functor. -/
structure FullyFaithful where
  /-- The inverse map `(F.obj X ⟶ F.obj Y) ⟶ (X ⟶ Y)` of `F.map`. -/
  preimage {X Y : C} (f : F.obj X ⟶ F.obj Y) : X ⟶ Y
  map_preimage {X Y : C} (f : F.obj X ⟶ F.obj Y) : F.map (preimage f) = f := by aesop_cat
  preimage_map {X Y : C} (f : X ⟶ Y) : preimage (F.map f) = f := by aesop_cat
goal: F.map (self.preimage f) = f

full_name: CategoryTheory.Functor.FullyFaithful.preimage
code: /-- Structure containing the data of inverse map `(F.obj X ⟶ F.obj Y) ⟶ (X ⟶ Y)` of `F.map`
in order to express that `F` is a fully faithful functor. -/
structure FullyFaithful where
  /-- The inverse map `(F.obj X ⟶ F.obj Y) ⟶ (X ⟶ Y)` of `F.map`. -/
  preimage {X Y : C} (f : F.obj X ⟶ F.obj Y) : X ⟶ Y
  map_preimage {X Y : C} (f : F.obj X ⟶ F.obj Y) : F.map (preimage f) = f := by aesop_cat
  preimage_map {X Y : C} (f : X ⟶ Y) : preimage (F.map f) = f := by aesop_cat
goal: X ⟶ Y

full_name: CategoryTheory.Functor.FullyFaithful
code: /-- Structure containing the data of inverse map `(F.obj X ⟶ F.obj Y) ⟶ (X ⟶ Y)` of `F.map`
in order to express that `F` is a fully faithful functor. -/
structure FullyFaithful where
  /-- The inverse map `(F.obj X ⟶ F.obj Y) ⟶ (X ⟶ Y)` of `F.map`. -/
  preimage {X Y : C} (f : F.obj X ⟶ F.obj Y) : X ⟶ Y
  map_preimage {X Y : C} (f : F.obj X ⟶ F.obj Y) : F.map (preimage f) = f := by aesop_cat
  preimage_map {X Y : C} (f : X ⟶ Y) : preimage (F.map f) = f := by aesop_cat
goal: Type (max (max u₁ v₁) v₂)

full_name: CategoryTheory.Functor.FullyFaithful.preimage_map
code: /-- Structure containing the data of inverse map `(F.obj X ⟶ F.obj Y) ⟶ (X ⟶ Y)` of `F.map`
in order to express that `F` is a fully faithful functor. -/
structure FullyFaithful where
  /-- The inverse map `(F.obj X ⟶ F.obj Y) ⟶ (X ⟶ Y)` of `F.map`. -/
  preimage {X Y : C} (f : F.obj X ⟶ F.obj Y) : X ⟶ Y
  map_preimage {X Y : C} (f : F.obj X ⟶ F.obj Y) : F.map (preimage f) = f := by aesop_cat
  preimage_map {X Y : C} (f : X ⟶ Y) : preimage (F.map f) = f := by aesop_cat
goal: self.preimage (F.map f) = f

full_name: CategoryTheory.Functor.FullyFaithful.ofFullyFaithful
code: /-- A `FullyFaithful` structure can be obtained from the assumption the `F` is both
full and faithful. -/
noncomputable def ofFullyFaithful [F.Full] [F.Faithful] :
    F.FullyFaithful 
goal: F.FullyFaithful

full_name: CategoryTheory.Functor.FullyFaithful.id
code: /-- The identity functor is fully faithful. -/
@[simps]
def id : (𝟭 C).FullyFaithful 
goal: (CategoryTheory.Functor.id C).FullyFaithful

full_name: CategoryTheory.Functor.FullyFaithful.id_preimage
code: /-- The identity functor is fully faithful. -/
@[simps]
def id : (𝟭 C).FullyFaithful 
goal: ∀ {X Y : C} (f : (CategoryTheory.Functor.id C).obj X ⟶ (CategoryTheory.Functor.id C).obj Y),
  (CategoryTheory.Functor.FullyFaithful.id C).preimage f = f

full_name: CategoryTheory.Functor.FullyFaithful.homEquiv_apply
code: /-- The equivalence `(X ⟶ Y) ≃ (F.obj X ⟶ F.obj Y)` given by `h : F.FullyFaithful`. -/
@[simps]
def homEquiv {X Y : C} : (X ⟶ Y) ≃ (F.obj X ⟶ F.obj Y) 
goal: ∀ (a : X ⟶ Y), hF.homEquiv a = F.map a

full_name: CategoryTheory.Functor.FullyFaithful.homEquiv
code: /-- The equivalence `(X ⟶ Y) ≃ (F.obj X ⟶ F.obj Y)` given by `h : F.FullyFaithful`. -/
@[simps]
def homEquiv {X Y : C} : (X ⟶ Y) ≃ (F.obj X ⟶ F.obj Y) 
goal: (X ⟶ Y) ≃ (F.obj X ⟶ F.obj Y)

full_name: CategoryTheory.Functor.FullyFaithful.homEquiv_symm_apply
code: /-- The equivalence `(X ⟶ Y) ≃ (F.obj X ⟶ F.obj Y)` given by `h : F.FullyFaithful`. -/
@[simps]
def homEquiv {X Y : C} : (X ⟶ Y) ≃ (F.obj X ⟶ F.obj Y) 
goal: hF.homEquiv.symm f = hF.preimage f

full_name: CategoryTheory.Functor.FullyFaithful.map_injective
code: lemma map_injective {X Y : C} {f g : X ⟶ Y} (h : F.map f = F.map g) : f = g 
goal: f = g

full_name: CategoryTheory.Functor.FullyFaithful.map_surjective
code: lemma map_surjective {X Y : C} :
    Function.Surjective (F.map : (X ⟶ Y) → (F.obj X ⟶ F.obj Y)) 
goal: Function.Surjective F.map

full_name: CategoryTheory.Functor.FullyFaithful.map_bijective
code: lemma map_bijective (X Y : C) :
    Function.Bijective (F.map : (X ⟶ Y) → (F.obj X ⟶ F.obj Y)) 
goal: Function.Bijective F.map

full_name: CategoryTheory.Functor.FullyFaithful.full
code: lemma full : F.Full 
goal: F.Full

full_name: CategoryTheory.Functor.FullyFaithful.faithful
code: lemma faithful : F.Faithful 
goal: F.Faithful

full_name: CategoryTheory.Functor.FullyFaithful.preimageIso
code: /-- The unique isomorphism `X ≅ Y` which induces an isomorphism `F.obj X ≅ F.obj Y`
when `hF : F.FullyFaithful`. -/
@[simps]
def preimageIso {X Y : C} (e : F.obj X ≅ F.obj Y) : X ≅ Y 
goal: X ≅ Y

full_name: CategoryTheory.Functor.FullyFaithful.preimageIso_hom
code: /-- The unique isomorphism `X ≅ Y` which induces an isomorphism `F.obj X ≅ F.obj Y`
when `hF : F.FullyFaithful`. -/
@[simps]
def preimageIso {X Y : C} (e : F.obj X ≅ F.obj Y) : X ≅ Y 
goal: (hF.preimageIso e).hom = hF.preimage e.hom

full_name: CategoryTheory.Functor.FullyFaithful.preimageIso_inv
code: /-- The unique isomorphism `X ≅ Y` which induces an isomorphism `F.obj X ≅ F.obj Y`
when `hF : F.FullyFaithful`. -/
@[simps]
def preimageIso {X Y : C} (e : F.obj X ≅ F.obj Y) : X ≅ Y 
goal: (hF.preimageIso e).inv = hF.preimage e.inv

full_name: CategoryTheory.Functor.FullyFaithful.isIso_of_isIso_map
code: lemma isIso_of_isIso_map (hF : F.FullyFaithful) {X Y : C} (f : X ⟶ Y) [IsIso (F.map f)] :
    IsIso f 
goal: CategoryTheory.IsIso f

full_name: CategoryTheory.Functor.FullyFaithful.isoEquiv_symm_apply
code: /-- The equivalence `(X ≅ Y) ≃ (F.obj X ≅ F.obj Y)` given by `h : F.FullyFaithful`. -/
@[simps]
def isoEquiv {X Y : C} : (X ≅ Y) ≃ (F.obj X ≅ F.obj Y) 
goal: hF.isoEquiv.symm e = hF.preimageIso e

full_name: CategoryTheory.Functor.FullyFaithful.isoEquiv
code: /-- The equivalence `(X ≅ Y) ≃ (F.obj X ≅ F.obj Y)` given by `h : F.FullyFaithful`. -/
@[simps]
def isoEquiv {X Y : C} : (X ≅ Y) ≃ (F.obj X ≅ F.obj Y) 
goal: (X ≅ Y) ≃ (F.obj X ≅ F.obj Y)

full_name: CategoryTheory.Functor.FullyFaithful.isoEquiv_apply
code: /-- The equivalence `(X ≅ Y) ≃ (F.obj X ≅ F.obj Y)` given by `h : F.FullyFaithful`. -/
@[simps]
def isoEquiv {X Y : C} : (X ≅ Y) ≃ (F.obj X ≅ F.obj Y) 
goal: hF.isoEquiv i = F.mapIso i

full_name: CategoryTheory.Functor.FullyFaithful.comp
code: /-- Fully faithful functors are stable by composition. -/
@[simps]
def comp {G : D ⥤ E} (hG : G.FullyFaithful) : (F ⋙ G).FullyFaithful 
goal: (F.comp G).FullyFaithful

full_name: CategoryTheory.Functor.FullyFaithful.comp_preimage
code: /-- Fully faithful functors are stable by composition. -/
@[simps]
def comp {G : D ⥤ E} (hG : G.FullyFaithful) : (F ⋙ G).FullyFaithful 
goal: ∀ {X Y : C} (f : (F.comp G).obj X ⟶ (F.comp G).obj Y), (hF.comp hG).preimage f = hF.preimage (hG.preimage f)

full_name: CategoryTheory.Functor.FullyFaithful.ofCompFaithful
code: /-- If `F ⋙ G` is fully faithful and `G` is faithful, then `F` is fully faithful. -/
def ofCompFaithful {G : D ⥤ E} [G.Faithful] (hFG : (F ⋙ G).FullyFaithful) :
    F.FullyFaithful 
goal: F.FullyFaithful

full_name: CategoryTheory.isIso_of_fully_faithful
code: /-- If the image of a morphism under a fully faithful functor in an isomorphism,
then the original morphisms is also an isomorphism.
-/
theorem isIso_of_fully_faithful (f : X ⟶ Y) [IsIso (F.map f)] : IsIso f 
goal: CategoryTheory.IsIso f

full_name: CategoryTheory.Functor.Full.id
code: instance Full.id : Full (𝟭 C) 
goal: (CategoryTheory.Functor.id C).Full

full_name: CategoryTheory.Functor.Faithful.id
code: instance Faithful.id : Functor.Faithful (𝟭 C) 
goal: (CategoryTheory.Functor.id C).Faithful

full_name: CategoryTheory.Functor.Faithful.comp
code: instance Faithful.comp [F.Faithful] [G.Faithful] :
    (F ⋙ G).Faithful  
goal: (F.comp G).Faithful

full_name: CategoryTheory.Functor.Faithful.of_comp
code: theorem Faithful.of_comp [(F ⋙ G).Faithful] : F.Faithful 
goal: F.Faithful

full_name: CategoryTheory.Functor.instFaithfulOfIsThin
code: instance (priority := 100) [Quiver.IsThin C] : F.Faithful 
goal: F.Faithful

full_name: CategoryTheory.Functor.Full.of_iso
code: /-- If `F` is full, and naturally isomorphic to some `F'`, then `F'` is also full. -/
lemma Full.of_iso [Full F] (α : F ≅ F') : Full F' 
goal: F'.Full

full_name: CategoryTheory.Functor.Faithful.of_iso
code: theorem Faithful.of_iso [F.Faithful] (α : F ≅ F') : F'.Faithful 
goal: F'.Faithful

full_name: CategoryTheory.Functor.Faithful.of_comp_iso
code: theorem Faithful.of_comp_iso {H : C ⥤ E} [H.Faithful] (h : F ⋙ G ≅ H) : F.Faithful 
goal: F.Faithful

full_name: CategoryTheory.Functor.Faithful.of_comp_eq
code: theorem Faithful.of_comp_eq {H : C ⥤ E} [ℋ : H.Faithful] (h : F ⋙ G = H) : F.Faithful 
goal: F.Faithful

full_name: CategoryTheory.Functor.Faithful.div
code: /-- “Divide” a functor by a faithful functor. -/
protected def Faithful.div (F : C ⥤ E) (G : D ⥤ E) [G.Faithful] (obj : C → D)
    (h_obj : ∀ X, G.obj (obj X) = F.obj X) (map : ∀ {X Y}, (X ⟶ Y) → (obj X ⟶ obj Y))
    (h_map : ∀ {X Y} {f : X ⟶ Y}, HEq (G.map (map f)) (F.map f)) : C ⥤ D 
goal: CategoryTheory.Functor C D

full_name: CategoryTheory.Functor.Faithful.div_comp
code: theorem Faithful.div_comp (F : C ⥤ E) [F.Faithful] (G : D ⥤ E) [G.Faithful] (obj : C → D)
    (h_obj : ∀ X, G.obj (obj X) = F.obj X) (map : ∀ {X Y}, (X ⟶ Y) → (obj X ⟶ obj Y))
    (h_map : ∀ {X Y} {f : X ⟶ Y}, HEq (G.map (map f)) (F.map f)) :
    Faithful.div F G obj @h_obj @map @h_map ⋙ G = F 
goal: (CategoryTheory.Functor.Faithful.div F G obj h_obj map h_map).comp G = F

full_name: CategoryTheory.Functor.Faithful.div_faithful
code: theorem Faithful.div_faithful (F : C ⥤ E) [F.Faithful] (G : D ⥤ E) [G.Faithful] (obj : C → D)
    (h_obj : ∀ X, G.obj (obj X) = F.obj X) (map : ∀ {X Y}, (X ⟶ Y) → (obj X ⟶ obj Y))
    (h_map : ∀ {X Y} {f : X ⟶ Y}, HEq (G.map (map f)) (F.map f)) :
    Functor.Faithful (Faithful.div F G obj @h_obj @map @h_map) 
goal: (CategoryTheory.Functor.Faithful.div F G obj h_obj map h_map).Faithful

full_name: CategoryTheory.Functor.Full.comp
code: instance Full.comp [Full F] [Full G] : Full (F ⋙ G) 
goal: (F.comp G).Full

full_name: CategoryTheory.Functor.Full.of_comp_faithful
code: /-- If `F ⋙ G` is full and `G` is faithful, then `F` is full. -/
lemma Full.of_comp_faithful [Full <| F ⋙ G] [G.Faithful] : Full F 
goal: F.Full

full_name: CategoryTheory.Functor.Full.of_comp_faithful_iso
code: /-- If `F ⋙ G` is full and `G` is faithful, then `F` is full. -/
lemma Full.of_comp_faithful_iso {F : C ⥤ D} {G : D ⥤ E} {H : C ⥤ E} [Full H] [G.Faithful]
    (h : F ⋙ G ≅ H) : Full F 
goal: F.Full

full_name: CategoryTheory.Functor.fullyFaithfulCancelRight
code: /-- Given a natural isomorphism between `F ⋙ H` and `G ⋙ H` for a fully faithful functor `H`, we
can 'cancel' it to give a natural iso between `F` and `G`.
-/
noncomputable def fullyFaithfulCancelRight {F G : C ⥤ D} (H : D ⥤ E) [Full H] [H.Faithful]
    (comp_iso : F ⋙ H ≅ G ⋙ H) : F ≅ G 
goal: F ≅ G

full_name: CategoryTheory.Functor.fullyFaithfulCancelRight_hom_app
code: @[simp]
theorem fullyFaithfulCancelRight_hom_app {F G : C ⥤ D} {H : D ⥤ E} [Full H] [H.Faithful]
    (comp_iso : F ⋙ H ≅ G ⋙ H) (X : C) :
    (fullyFaithfulCancelRight H comp_iso).hom.app X = H.preimage (comp_iso.hom.app X) 
goal: (CategoryTheory.Functor.fullyFaithfulCancelRight H comp_iso).hom.app X = H.preimage (comp_iso.hom.app X)

full_name: CategoryTheory.Functor.fullyFaithfulCancelRight_inv_app
code: @[simp]
theorem fullyFaithfulCancelRight_inv_app {F G : C ⥤ D} {H : D ⥤ E} [Full H] [H.Faithful]
    (comp_iso : F ⋙ H ≅ G ⋙ H) (X : C) :
    (fullyFaithfulCancelRight H comp_iso).inv.app X = H.preimage (comp_iso.inv.app X) 
goal: (CategoryTheory.Functor.fullyFaithfulCancelRight H comp_iso).inv.app X = H.preimage (comp_iso.inv.app X)