/-
Copyright (c) 2018 Scott Morrison. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Scott Morrison, Johannes Hölzl, Reid Barton, Sean Leather, Yury Kudryashov

! This file was ported from Lean 3 source module category_theory.concrete_category.basic
! leanprover-community/mathlib commit f47581155c818e6361af4e4fda60d27d020c226b
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.CategoryTheory.Types
import Mathbin.CategoryTheory.Functor.EpiMono
import Mathbin.CategoryTheory.Limits.Constructions.EpiMono

/-!
# Concrete categories

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

A concrete category is a category `C` with a fixed faithful functor
`forget : C ⥤ Type*`.  We define concrete categories using `class
concrete_category`.  In particular, we impose no restrictions on the
carrier type `C`, so `Type` is a concrete category with the identity
forgetful functor.

Each concrete category `C` comes with a canonical faithful functor
`forget C : C ⥤ Type*`.  We say that a concrete category `C` admits a
*forgetful functor* to a concrete category `D`, if it has a functor
`forget₂ C D : C ⥤ D` such that `(forget₂ C D) ⋙ (forget D) = forget C`,
see `class has_forget₂`.  Due to `faithful.div_comp`, it suffices
to verify that `forget₂.obj` and `forget₂.map` agree with the equality
above; then `forget₂` will satisfy the functor laws automatically, see
`has_forget₂.mk'`.

Two classes helping construct concrete categories in the two most
common cases are provided in the files `bundled_hom` and
`unbundled_hom`, see their documentation for details.

## References

See [Ahrens and Lumsdaine, *Displayed Categories*][ahrens2017] for
related work.
-/

universe w v v' u

namespace CategoryTheory

open CategoryTheory.Limits

#print CategoryTheory.ConcreteCategory /-
/- ./././Mathport/Syntax/Translate/Command.lean:388:30: infer kinds are unsupported in Lean 4: #[`forget] [] -/
/-- A concrete category is a category `C` with a fixed faithful functor `forget : C ⥤ Type`.

Note that `concrete_category` potentially depends on three independent universe levels,
* the universe level `w` appearing in `forget : C ⥤ Type w`
* the universe level `v` of the morphisms (i.e. we have a `category.{v} C`)
* the universe level `u` of the objects (i.e `C : Type u`)
They are specified that order, to avoid unnecessary universe annotations.
-/
class ConcreteCategory (C : Type u) [Category.{v} C] where
  forget : C ⥤ Type w
  [forget_faithful : Faithful forget]
#align category_theory.concrete_category CategoryTheory.ConcreteCategory
-/

attribute [instance] concrete_category.forget_faithful

#print CategoryTheory.forget /-
/-- The forgetful functor from a concrete category to `Type u`. -/
@[reducible]
def forget (C : Type v) [Category C] [ConcreteCategory.{u} C] : C ⥤ Type u :=
  ConcreteCategory.Forget C
#align category_theory.forget CategoryTheory.forget
-/

#print CategoryTheory.ConcreteCategory.types /-
instance ConcreteCategory.types : ConcreteCategory (Type u) where forget := 𝟭 _
#align category_theory.concrete_category.types CategoryTheory.ConcreteCategory.types
-/

#print CategoryTheory.ConcreteCategory.hasCoeToSort /-
/-- Provide a coercion to `Type u` for a concrete category. This is not marked as an instance
as it could potentially apply to every type, and so is too expensive in typeclass search.

You can use it on particular examples as:
```
instance : has_coe_to_sort X := concrete_category.has_coe_to_sort X
```
-/
def ConcreteCategory.hasCoeToSort (C : Type v) [Category C] [ConcreteCategory C] :
    CoeSort C (Type u) :=
  ⟨(ConcreteCategory.Forget C).obj⟩
#align category_theory.concrete_category.has_coe_to_sort CategoryTheory.ConcreteCategory.hasCoeToSort
-/

section

attribute [local instance] concrete_category.has_coe_to_sort

variable {C : Type v} [Category C] [ConcreteCategory C]

/- warning: category_theory.forget_obj_eq_coe -> CategoryTheory.forget_obj_eq_coe is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C}, Eq.{succ (succ u3)} Type.{u3} (CategoryTheory.Functor.obj.{u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2) X) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C}, Eq.{succ (succ u2)} Type.{u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X)
Case conversion may be inaccurate. Consider using '#align category_theory.forget_obj_eq_coe CategoryTheory.forget_obj_eq_coeₓ'. -/
@[simp]
theorem forget_obj_eq_coe {X : C} : (forget C).obj X = X :=
  rfl
#align category_theory.forget_obj_eq_coe CategoryTheory.forget_obj_eq_coe

/- warning: category_theory.concrete_category.has_coe_to_fun -> CategoryTheory.ConcreteCategory.hasCoeToFun is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C}, CoeFun.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y))
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u3, u2} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u1, u3, u2} C _inst_1] {X : C} {Y : C}, CoeFun.{succ u3, succ u1} (Quiver.Hom.{succ u3, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u2} C (CategoryTheory.Category.toCategoryStruct.{u3, u2} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u3, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u2} C (CategoryTheory.Category.toCategoryStruct.{u3, u2} C _inst_1)) X Y) => (Prefunctor.obj.{succ u3, succ u1, u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u2} C (CategoryTheory.Category.toCategoryStruct.{u3, u2} C _inst_1)) Type.{u1} (CategoryTheory.CategoryStruct.toQuiver.{u1, succ u1} Type.{u1} (CategoryTheory.Category.toCategoryStruct.{u1, succ u1} Type.{u1} CategoryTheory.types.{u1})) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u2, succ u1} C _inst_1 Type.{u1} CategoryTheory.types.{u1} (CategoryTheory.ConcreteCategory.Forget.{u1, u3, u2} C _inst_1 _inst_2)) X) -> (Prefunctor.obj.{succ u3, succ u1, u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u2} C (CategoryTheory.Category.toCategoryStruct.{u3, u2} C _inst_1)) Type.{u1} (CategoryTheory.CategoryStruct.toQuiver.{u1, succ u1} Type.{u1} (CategoryTheory.Category.toCategoryStruct.{u1, succ u1} Type.{u1} CategoryTheory.types.{u1})) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u2, succ u1} C _inst_1 Type.{u1} CategoryTheory.types.{u1} (CategoryTheory.ConcreteCategory.Forget.{u1, u3, u2} C _inst_1 _inst_2)) Y))
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.has_coe_to_fun CategoryTheory.ConcreteCategory.hasCoeToFunₓ'. -/
/-- Usually a bundled hom structure already has a coercion to function
that works with different universes. So we don't use this as a global instance. -/
def ConcreteCategory.hasCoeToFun {X Y : C} : CoeFun (X ⟶ Y) fun f => X → Y :=
  ⟨fun f => (forget _).map f⟩
#align category_theory.concrete_category.has_coe_to_fun CategoryTheory.ConcreteCategory.hasCoeToFun

attribute [local instance] concrete_category.has_coe_to_fun

/- warning: category_theory.concrete_category.hom_ext -> CategoryTheory.ConcreteCategory.hom_ext is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y), (forall (x : coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X), Eq.{succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f x) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) g x)) -> (Eq.{succ u2} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) f g)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) (g : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y), (forall (x : Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X), Eq.{succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f x) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y g x)) -> (Eq.{succ u1} (Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) f g)
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.hom_ext CategoryTheory.ConcreteCategory.hom_extₓ'. -/
/-- In any concrete category, we can test equality of morphisms by pointwise evaluations.-/
theorem ConcreteCategory.hom_ext {X Y : C} (f g : X ⟶ Y) (w : ∀ x : X, f x = g x) : f = g :=
  by
  apply faithful.map_injective (forget C)
  ext
  exact w x
#align category_theory.concrete_category.hom_ext CategoryTheory.ConcreteCategory.hom_ext

/- warning: category_theory.forget_map_eq_coe -> CategoryTheory.forget_map_eq_coe is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y), Eq.{succ u3} (Quiver.Hom.{succ u3, succ u3} Type.{u3} (CategoryTheory.CategoryStruct.toQuiver.{u3, succ u3} Type.{u3} (CategoryTheory.Category.toCategoryStruct.{u3, succ u3} Type.{u3} CategoryTheory.types.{u3})) (CategoryTheory.Functor.obj.{u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2) X) (CategoryTheory.Functor.obj.{u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.Functor.map.{u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2) X Y f) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y), Eq.{succ u2} (Quiver.Hom.{succ u2, succ u2} Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y)) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f)
Case conversion may be inaccurate. Consider using '#align category_theory.forget_map_eq_coe CategoryTheory.forget_map_eq_coeₓ'. -/
@[simp]
theorem forget_map_eq_coe {X Y : C} (f : X ⟶ Y) : (forget C).map f = f :=
  rfl
#align category_theory.forget_map_eq_coe CategoryTheory.forget_map_eq_coe

/- warning: category_theory.congr_hom -> CategoryTheory.congr_hom is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y}, (Eq.{succ u2} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) f g) -> (forall (x : coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X), Eq.{succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f x) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) g x))
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y} {g : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y}, (Eq.{succ u1} (Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) f g) -> (forall (x : Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X), Eq.{succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f x) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y g x))
Case conversion may be inaccurate. Consider using '#align category_theory.congr_hom CategoryTheory.congr_homₓ'. -/
/-- Analogue of `congr_fun h x`,
when `h : f = g` is an equality between morphisms in a concrete category.
-/
theorem congr_hom {X Y : C} {f g : X ⟶ Y} (h : f = g) (x : X) : f x = g x :=
  congr_fun (congr_arg (fun k : X ⟶ Y => (k : X → Y)) h) x
#align category_theory.congr_hom CategoryTheory.congr_hom

/- warning: category_theory.coe_id -> CategoryTheory.coe_id is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C}, Eq.{succ u3} ((fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X X) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X)) (CategoryTheory.CategoryStruct.id.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) X)) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X X) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X X) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X X) (CategoryTheory.CategoryStruct.id.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) X)) (id.{succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X))
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C}, Eq.{succ u2} (Quiver.Hom.{succ u2, succ u2} Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X)) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X X (CategoryTheory.CategoryStruct.id.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1) X)) (id.{succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X))
Case conversion may be inaccurate. Consider using '#align category_theory.coe_id CategoryTheory.coe_idₓ'. -/
theorem coe_id {X : C} : (𝟙 X : X → X) = id :=
  (forget _).map_id X
#align category_theory.coe_id CategoryTheory.coe_id

/- warning: category_theory.coe_comp -> CategoryTheory.coe_comp is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} {Z : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z), Eq.{succ u3} ((fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Z)) (CategoryTheory.CategoryStruct.comp.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) X Y Z f g)) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Z)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Z) (CategoryTheory.CategoryStruct.comp.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) X Y Z f g)) (Function.comp.{succ u3, succ u3, succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Z) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Z)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 Y Z) g) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f))
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} {Z : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) (g : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Y Z), Eq.{succ u2} (Quiver.Hom.{succ u2, succ u2} Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Z)) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Z (CategoryTheory.CategoryStruct.comp.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1) X Y Z f g)) (Function.comp.{succ u2, succ u2, succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Z) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y Z g) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f))
Case conversion may be inaccurate. Consider using '#align category_theory.coe_comp CategoryTheory.coe_compₓ'. -/
theorem coe_comp {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g : X → Z) = g ∘ f :=
  (forget _).map_comp f g
#align category_theory.coe_comp CategoryTheory.coe_comp

/- warning: category_theory.id_apply -> CategoryTheory.id_apply is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} (x : coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X), Eq.{succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X X) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X X) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X X) (CategoryTheory.CategoryStruct.id.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) X) x) x
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} (x : Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X), Eq.{succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X X (CategoryTheory.CategoryStruct.id.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1) X) x) x
Case conversion may be inaccurate. Consider using '#align category_theory.id_apply CategoryTheory.id_applyₓ'. -/
@[simp]
theorem id_apply {X : C} (x : X) : (𝟙 X : X → X) x = x :=
  congr_fun ((forget _).map_id X) x
#align category_theory.id_apply CategoryTheory.id_apply

/- warning: category_theory.comp_apply -> CategoryTheory.comp_apply is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} {Z : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z) (x : coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X), Eq.{succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Z) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Z) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Z)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Z) (CategoryTheory.CategoryStruct.comp.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) X Y Z f g) x) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) Y Z) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Z)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 Y Z) g (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f x))
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} {Z : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) (g : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Y Z) (x : Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X), Eq.{succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Z) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Z (CategoryTheory.CategoryStruct.comp.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1) X Y Z f g) x) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y Z g (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f x))
Case conversion may be inaccurate. Consider using '#align category_theory.comp_apply CategoryTheory.comp_applyₓ'. -/
@[simp]
theorem comp_apply {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : (f ≫ g) x = g (f x) :=
  congr_fun ((forget _).map_comp _ _) x
#align category_theory.comp_apply CategoryTheory.comp_apply

/- warning: category_theory.concrete_category.congr_hom -> CategoryTheory.ConcreteCategory.congr_hom is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} {f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y} {g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y}, (Eq.{succ u2} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) f g) -> (forall (x : coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X), Eq.{succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f x) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) g x))
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} {f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y} {g : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y}, (Eq.{succ u1} (Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) f g) -> (forall (x : Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X), Eq.{succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f x) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y g x))
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.congr_hom CategoryTheory.ConcreteCategory.congr_homₓ'. -/
theorem ConcreteCategory.congr_hom {X Y : C} {f g : X ⟶ Y} (h : f = g) (x : X) : f x = g x :=
  congr_fun (congr_arg (fun f : X ⟶ Y => (f : X → Y)) h) x
#align category_theory.concrete_category.congr_hom CategoryTheory.ConcreteCategory.congr_hom

/- warning: category_theory.concrete_category.congr_arg -> CategoryTheory.ConcreteCategory.congr_arg is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) {x : coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X} {x' : coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X}, (Eq.{succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) x x') -> (Eq.{succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f x) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f x'))
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) {x : Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X} {x' : Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X}, (Eq.{succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.ConcreteCategory.Forget.{u2, u1, u3} C _inst_1 _inst_2)) X) x x') -> (Eq.{succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f x) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f x'))
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.congr_arg CategoryTheory.ConcreteCategory.congr_argₓ'. -/
theorem ConcreteCategory.congr_arg {X Y : C} (f : X ⟶ Y) {x x' : X} (h : x = x') : f x = f x' :=
  congr_arg (f : X → Y) h
#align category_theory.concrete_category.congr_arg CategoryTheory.ConcreteCategory.congr_arg

/- warning: category_theory.concrete_category.mono_of_injective -> CategoryTheory.ConcreteCategory.mono_of_injective is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y), (Function.Injective.{succ u3, succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f)) -> (CategoryTheory.Mono.{u2, u1} C _inst_1 X Y f)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y), (Function.Injective.{succ u2, succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f)) -> (CategoryTheory.Mono.{u1, u3} C _inst_1 X Y f)
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.mono_of_injective CategoryTheory.ConcreteCategory.mono_of_injectiveₓ'. -/
/-- In any concrete category, injective morphisms are monomorphisms. -/
theorem ConcreteCategory.mono_of_injective {X Y : C} (f : X ⟶ Y) (i : Function.Injective f) :
    Mono f :=
  (forget C).mono_of_mono_map ((mono_iff_injective f).2 i)
#align category_theory.concrete_category.mono_of_injective CategoryTheory.ConcreteCategory.mono_of_injective

/- warning: category_theory.concrete_category.injective_of_mono_of_preserves_pullback -> CategoryTheory.ConcreteCategory.injective_of_mono_of_preservesPullback is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) [_inst_3 : CategoryTheory.Mono.{u2, u1} C _inst_1 X Y f] [_inst_4 : CategoryTheory.Limits.PreservesLimitsOfShape.{0, 0, u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} CategoryTheory.Limits.WalkingCospan (CategoryTheory.Limits.WidePullbackShape.category.{0} CategoryTheory.Limits.WalkingPair) (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2)], Function.Injective.{succ u3, succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) [_inst_3 : CategoryTheory.Mono.{u1, u3} C _inst_1 X Y f] [_inst_4 : CategoryTheory.Limits.PreservesLimitsOfShape.{0, 0, u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} CategoryTheory.Limits.WalkingCospan (CategoryTheory.Limits.WidePullbackShape.category.{0} CategoryTheory.Limits.WalkingPair) (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)], Function.Injective.{succ u2, succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f)
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.injective_of_mono_of_preserves_pullback CategoryTheory.ConcreteCategory.injective_of_mono_of_preservesPullbackₓ'. -/
theorem ConcreteCategory.injective_of_mono_of_preservesPullback {X Y : C} (f : X ⟶ Y) [Mono f]
    [PreservesLimitsOfShape WalkingCospan (forget C)] : Function.Injective f :=
  (mono_iff_injective ((forget C).map f)).mp inferInstance
#align category_theory.concrete_category.injective_of_mono_of_preserves_pullback CategoryTheory.ConcreteCategory.injective_of_mono_of_preservesPullback

/- warning: category_theory.concrete_category.mono_iff_injective_of_preserves_pullback -> CategoryTheory.ConcreteCategory.mono_iff_injective_of_preservesPullback is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) [_inst_3 : CategoryTheory.Limits.PreservesLimitsOfShape.{0, 0, u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} CategoryTheory.Limits.WalkingCospan (CategoryTheory.Limits.WidePullbackShape.category.{0} CategoryTheory.Limits.WalkingPair) (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2)], Iff (CategoryTheory.Mono.{u2, u1} C _inst_1 X Y f) (Function.Injective.{succ u3, succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f))
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) [_inst_3 : CategoryTheory.Limits.PreservesLimitsOfShape.{0, 0, u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} CategoryTheory.Limits.WalkingCospan (CategoryTheory.Limits.WidePullbackShape.category.{0} CategoryTheory.Limits.WalkingPair) (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)], Iff (CategoryTheory.Mono.{u1, u3} C _inst_1 X Y f) (Function.Injective.{succ u2, succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f))
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.mono_iff_injective_of_preserves_pullback CategoryTheory.ConcreteCategory.mono_iff_injective_of_preservesPullbackₓ'. -/
theorem ConcreteCategory.mono_iff_injective_of_preservesPullback {X Y : C} (f : X ⟶ Y)
    [PreservesLimitsOfShape WalkingCospan (forget C)] : Mono f ↔ Function.Injective f :=
  ((forget C).mono_map_iff_mono _).symm.trans (mono_iff_injective _)
#align category_theory.concrete_category.mono_iff_injective_of_preserves_pullback CategoryTheory.ConcreteCategory.mono_iff_injective_of_preservesPullback

/- warning: category_theory.concrete_category.epi_of_surjective -> CategoryTheory.ConcreteCategory.epi_of_surjective is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y), (Function.Surjective.{succ u3, succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f)) -> (CategoryTheory.Epi.{u2, u1} C _inst_1 X Y f)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y), (Function.Surjective.{succ u2, succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f)) -> (CategoryTheory.Epi.{u1, u3} C _inst_1 X Y f)
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.epi_of_surjective CategoryTheory.ConcreteCategory.epi_of_surjectiveₓ'. -/
/-- In any concrete category, surjective morphisms are epimorphisms. -/
theorem ConcreteCategory.epi_of_surjective {X Y : C} (f : X ⟶ Y) (s : Function.Surjective f) :
    Epi f :=
  (forget C).epi_of_epi_map ((epi_iff_surjective f).2 s)
#align category_theory.concrete_category.epi_of_surjective CategoryTheory.ConcreteCategory.epi_of_surjective

/- warning: category_theory.concrete_category.surjective_of_epi_of_preserves_pushout -> CategoryTheory.ConcreteCategory.surjective_of_epi_of_preservesPushout is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) [_inst_3 : CategoryTheory.Epi.{u2, u1} C _inst_1 X Y f] [_inst_4 : CategoryTheory.Limits.PreservesColimitsOfShape.{0, 0, u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} CategoryTheory.Limits.WalkingSpan (CategoryTheory.Limits.WidePushoutShape.category.{0} CategoryTheory.Limits.WalkingPair) (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2)], Function.Surjective.{succ u3, succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) [_inst_3 : CategoryTheory.Epi.{u1, u3} C _inst_1 X Y f] [_inst_4 : CategoryTheory.Limits.PreservesColimitsOfShape.{0, 0, u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} CategoryTheory.Limits.WalkingSpan (CategoryTheory.Limits.WidePushoutShape.category.{0} CategoryTheory.Limits.WalkingPair) (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)], Function.Surjective.{succ u2, succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f)
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.surjective_of_epi_of_preserves_pushout CategoryTheory.ConcreteCategory.surjective_of_epi_of_preservesPushoutₓ'. -/
theorem ConcreteCategory.surjective_of_epi_of_preservesPushout {X Y : C} (f : X ⟶ Y) [Epi f]
    [PreservesColimitsOfShape WalkingSpan (forget C)] : Function.Surjective f :=
  (epi_iff_surjective ((forget C).map f)).mp inferInstance
#align category_theory.concrete_category.surjective_of_epi_of_preserves_pushout CategoryTheory.ConcreteCategory.surjective_of_epi_of_preservesPushout

/- warning: category_theory.concrete_category.epi_iff_surjective_of_preserves_pushout -> CategoryTheory.ConcreteCategory.epi_iff_surjective_of_preservesPushout is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) [_inst_3 : CategoryTheory.Limits.PreservesColimitsOfShape.{0, 0, u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} CategoryTheory.Limits.WalkingSpan (CategoryTheory.Limits.WidePushoutShape.category.{0} CategoryTheory.Limits.WalkingPair) (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2)], Iff (CategoryTheory.Epi.{u2, u1} C _inst_1 X Y f) (Function.Surjective.{succ u3, succ u3} (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y) (coeFn.{succ u2, succ u3} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) (fun (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) => (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) X) -> (coeSort.{succ u1, succ (succ u3)} C Type.{u3} (CategoryTheory.ConcreteCategory.hasCoeToSort.{u1, u3, u2} C _inst_1 _inst_2) Y)) (CategoryTheory.ConcreteCategory.hasCoeToFun.{u1, u2, u3} C _inst_1 _inst_2 X Y) f))
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) [_inst_3 : CategoryTheory.Limits.PreservesColimitsOfShape.{0, 0, u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} CategoryTheory.Limits.WalkingSpan (CategoryTheory.Limits.WidePushoutShape.category.{0} CategoryTheory.Limits.WalkingPair) (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)], Iff (CategoryTheory.Epi.{u1, u3} C _inst_1 X Y f) (Function.Surjective.{succ u2, succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f))
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.epi_iff_surjective_of_preserves_pushout CategoryTheory.ConcreteCategory.epi_iff_surjective_of_preservesPushoutₓ'. -/
theorem ConcreteCategory.epi_iff_surjective_of_preservesPushout {X Y : C} (f : X ⟶ Y)
    [PreservesColimitsOfShape WalkingSpan (forget C)] : Epi f ↔ Function.Surjective f :=
  ((forget C).epi_map_iff_epi _).symm.trans (epi_iff_surjective _)
#align category_theory.concrete_category.epi_iff_surjective_of_preserves_pushout CategoryTheory.ConcreteCategory.epi_iff_surjective_of_preservesPushout

/- warning: category_theory.concrete_category.bijective_of_is_iso -> CategoryTheory.ConcreteCategory.bijective_of_isIso is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u3, u2, u1} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y) [_inst_3 : CategoryTheory.IsIso.{u2, u1} C _inst_1 X Y f], Function.Bijective.{succ u3, succ u3} (CategoryTheory.Functor.obj.{u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2) X) (CategoryTheory.Functor.obj.{u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2) Y) (CategoryTheory.Functor.map.{u2, u3, u1, succ u3} C _inst_1 Type.{u3} CategoryTheory.types.{u3} (CategoryTheory.forget.{u1, u3, u2} C _inst_1 _inst_2) X Y f)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u1, u3} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u2, u1, u3} C _inst_1] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) X Y) [_inst_3 : CategoryTheory.IsIso.{u1, u3} C _inst_1 X Y f], Function.Bijective.{succ u2, succ u2} (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) Y) (Prefunctor.map.{succ u1, succ u2, u3, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u3} C (CategoryTheory.Category.toCategoryStruct.{u1, u3} C _inst_1)) Type.{u2} (CategoryTheory.CategoryStruct.toQuiver.{u2, succ u2} Type.{u2} (CategoryTheory.Category.toCategoryStruct.{u2, succ u2} Type.{u2} CategoryTheory.types.{u2})) (CategoryTheory.Functor.toPrefunctor.{u1, u2, u3, succ u2} C _inst_1 Type.{u2} CategoryTheory.types.{u2} (CategoryTheory.forget.{u3, u2, u1} C _inst_1 _inst_2)) X Y f)
Case conversion may be inaccurate. Consider using '#align category_theory.concrete_category.bijective_of_is_iso CategoryTheory.ConcreteCategory.bijective_of_isIsoₓ'. -/
theorem ConcreteCategory.bijective_of_isIso {X Y : C} (f : X ⟶ Y) [IsIso f] :
    Function.Bijective ((forget C).map f) :=
  by
  rw [← is_iso_iff_bijective]
  infer_instance
#align category_theory.concrete_category.bijective_of_is_iso CategoryTheory.ConcreteCategory.bijective_of_isIso

#print CategoryTheory.ConcreteCategory.hasCoeToFun_Type /-
@[simp]
theorem ConcreteCategory.hasCoeToFun_Type {X Y : Type u} (f : X ⟶ Y) : coeFn f = f :=
  rfl
#align category_theory.concrete_category.has_coe_to_fun_Type CategoryTheory.ConcreteCategory.hasCoeToFun_Type
-/

end

#print CategoryTheory.HasForget₂ /-
/-- `has_forget₂ C D`, where `C` and `D` are both concrete categories, provides a functor
`forget₂ C D : C ⥤ D` and a proof that `forget₂ ⋙ (forget D) = forget C`.
-/
class HasForget₂ (C : Type v) (D : Type v') [Category C] [ConcreteCategory.{u} C] [Category D]
  [ConcreteCategory.{u} D] where
  forget₂ : C ⥤ D
  forget_comp : forget₂ ⋙ forget D = forget C := by obviously
#align category_theory.has_forget₂ CategoryTheory.HasForget₂
-/

#print CategoryTheory.forget₂ /-
/-- The forgetful functor `C ⥤ D` between concrete categories for which we have an instance
`has_forget₂ C `. -/
@[reducible]
def forget₂ (C : Type v) (D : Type v') [Category C] [ConcreteCategory C] [Category D]
    [ConcreteCategory D] [HasForget₂ C D] : C ⥤ D :=
  HasForget₂.forget₂
#align category_theory.forget₂ CategoryTheory.forget₂
-/

#print CategoryTheory.forget₂_faithful /-
instance forget₂_faithful (C : Type v) (D : Type v') [Category C] [ConcreteCategory C] [Category D]
    [ConcreteCategory D] [HasForget₂ C D] : Faithful (forget₂ C D) :=
  HasForget₂.forget_comp.faithful_of_comp
#align category_theory.forget₂_faithful CategoryTheory.forget₂_faithful
-/

#print CategoryTheory.forget₂_preservesMonomorphisms /-
instance forget₂_preservesMonomorphisms (C : Type v) (D : Type v') [Category C] [ConcreteCategory C]
    [Category D] [ConcreteCategory D] [HasForget₂ C D] [(forget C).PreservesMonomorphisms] :
    (forget₂ C D).PreservesMonomorphisms :=
  have : (forget₂ C D ⋙ forget D).PreservesMonomorphisms :=
    by
    simp only [has_forget₂.forget_comp]
    infer_instance
  functor.preserves_monomorphisms_of_preserves_of_reflects _ (forget D)
#align category_theory.forget₂_preserves_monomorphisms CategoryTheory.forget₂_preservesMonomorphisms
-/

#print CategoryTheory.forget₂_preservesEpimorphisms /-
instance forget₂_preservesEpimorphisms (C : Type v) (D : Type v') [Category C] [ConcreteCategory C]
    [Category D] [ConcreteCategory D] [HasForget₂ C D] [(forget C).PreservesEpimorphisms] :
    (forget₂ C D).PreservesEpimorphisms :=
  have : (forget₂ C D ⋙ forget D).PreservesEpimorphisms :=
    by
    simp only [has_forget₂.forget_comp]
    infer_instance
  functor.preserves_epimorphisms_of_preserves_of_reflects _ (forget D)
#align category_theory.forget₂_preserves_epimorphisms CategoryTheory.forget₂_preservesEpimorphisms
-/

#print CategoryTheory.InducedCategory.concreteCategory /-
instance InducedCategory.concreteCategory {C : Type v} {D : Type v'} [Category D]
    [ConcreteCategory D] (f : C → D) : ConcreteCategory (InducedCategory D f)
    where forget := inducedFunctor f ⋙ forget D
#align category_theory.induced_category.concrete_category CategoryTheory.InducedCategory.concreteCategory
-/

#print CategoryTheory.InducedCategory.hasForget₂ /-
instance InducedCategory.hasForget₂ {C : Type v} {D : Type v'} [Category D] [ConcreteCategory D]
    (f : C → D) : HasForget₂ (InducedCategory D f) D
    where
  forget₂ := inducedFunctor f
  forget_comp := rfl
#align category_theory.induced_category.has_forget₂ CategoryTheory.InducedCategory.hasForget₂
-/

instance FullSubcategory.concreteCategory {C : Type v} [Category C] [ConcreteCategory C]
    (Z : C → Prop) : ConcreteCategory (FullSubcategory Z)
    where forget := fullSubcategoryInclusion Z ⋙ forget C
#align category_theory.full_subcategory.concrete_category CategoryTheory.FullSubcategoryₓ.concreteCategory

instance FullSubcategory.hasForget₂ {C : Type v} [Category C] [ConcreteCategory C] (Z : C → Prop) :
    HasForget₂ (FullSubcategory Z) C
    where
  forget₂ := fullSubcategoryInclusion Z
  forget_comp := rfl
#align category_theory.full_subcategory.has_forget₂ CategoryTheory.FullSubcategoryₓ.hasForget₂

/- warning: category_theory.has_forget₂.mk' -> CategoryTheory.HasForget₂.mk' is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} {D : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u3, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u4, u3, u1} C _inst_1] [_inst_3 : CategoryTheory.Category.{u5, u2} D] [_inst_4 : CategoryTheory.ConcreteCategory.{u4, u5, u2} D _inst_3] (obj : C -> D), (forall (X : C), Eq.{succ (succ u4)} Type.{u4} (CategoryTheory.Functor.obj.{u5, u4, u2, succ u4} D _inst_3 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u2, u4, u5} D _inst_3 _inst_4) (obj X)) (CategoryTheory.Functor.obj.{u3, u4, u1, succ u4} C _inst_1 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u1, u4, u3} C _inst_1 _inst_2) X)) -> (forall (map : forall {X : C} {Y : C}, (Quiver.Hom.{succ u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} C (CategoryTheory.Category.toCategoryStruct.{u3, u1} C _inst_1)) X Y) -> (Quiver.Hom.{succ u5, u2} D (CategoryTheory.CategoryStruct.toQuiver.{u5, u2} D (CategoryTheory.Category.toCategoryStruct.{u5, u2} D _inst_3)) (obj X) (obj Y))), (forall {X : C} {Y : C} {f : Quiver.Hom.{succ u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} C (CategoryTheory.Category.toCategoryStruct.{u3, u1} C _inst_1)) X Y}, HEq.{succ u4} (Quiver.Hom.{succ u4, succ u4} Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.obj.{u5, u4, u2, succ u4} D _inst_3 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u2, u4, u5} D _inst_3 _inst_4) (obj X)) (CategoryTheory.Functor.obj.{u5, u4, u2, succ u4} D _inst_3 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u2, u4, u5} D _inst_3 _inst_4) (obj Y))) (CategoryTheory.Functor.map.{u5, u4, u2, succ u4} D _inst_3 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u2, u4, u5} D _inst_3 _inst_4) (obj X) (obj Y) (map X Y f)) (Quiver.Hom.{succ u4, succ u4} Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.obj.{u3, u4, u1, succ u4} C _inst_1 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u1, u4, u3} C _inst_1 _inst_2) X) (CategoryTheory.Functor.obj.{u3, u4, u1, succ u4} C _inst_1 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u1, u4, u3} C _inst_1 _inst_2) Y)) (CategoryTheory.Functor.map.{u3, u4, u1, succ u4} C _inst_1 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u1, u4, u3} C _inst_1 _inst_2) X Y f)) -> (CategoryTheory.HasForget₂.{u1, u2, u4, u3, u5} C D _inst_1 _inst_2 _inst_3 _inst_4))
but is expected to have type
  forall {C : Type.{u1}} {D : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u3, u1} C] [_inst_2 : CategoryTheory.ConcreteCategory.{u4, u3, u1} C _inst_1] [_inst_3 : CategoryTheory.Category.{u5, u2} D] [_inst_4 : CategoryTheory.ConcreteCategory.{u4, u5, u2} D _inst_3] (obj : C -> D), (forall (X : C), Eq.{succ (succ u4)} Type.{u4} (Prefunctor.obj.{succ u5, succ u4, u2, succ u4} D (CategoryTheory.CategoryStruct.toQuiver.{u5, u2} D (CategoryTheory.Category.toCategoryStruct.{u5, u2} D _inst_3)) Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.toPrefunctor.{u5, u4, u2, succ u4} D _inst_3 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u2, u4, u5} D _inst_3 _inst_4)) (obj X)) (Prefunctor.obj.{succ u3, succ u4, u1, succ u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} C (CategoryTheory.Category.toCategoryStruct.{u3, u1} C _inst_1)) Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.toPrefunctor.{u3, u4, u1, succ u4} C _inst_1 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u1, u4, u3} C _inst_1 _inst_2)) X)) -> (forall (map : forall {X : C} {Y : C}, (Quiver.Hom.{succ u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} C (CategoryTheory.Category.toCategoryStruct.{u3, u1} C _inst_1)) X Y) -> (Quiver.Hom.{succ u5, u2} D (CategoryTheory.CategoryStruct.toQuiver.{u5, u2} D (CategoryTheory.Category.toCategoryStruct.{u5, u2} D _inst_3)) (obj X) (obj Y))), (forall {X : C} {Y : C} {f : Quiver.Hom.{succ u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} C (CategoryTheory.Category.toCategoryStruct.{u3, u1} C _inst_1)) X Y}, HEq.{succ u4} (Quiver.Hom.{succ u4, succ u4} Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (Prefunctor.obj.{succ u5, succ u4, u2, succ u4} D (CategoryTheory.CategoryStruct.toQuiver.{u5, u2} D (CategoryTheory.Category.toCategoryStruct.{u5, u2} D _inst_3)) Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.toPrefunctor.{u5, u4, u2, succ u4} D _inst_3 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u2, u4, u5} D _inst_3 _inst_4)) (obj X)) (Prefunctor.obj.{succ u5, succ u4, u2, succ u4} D (CategoryTheory.CategoryStruct.toQuiver.{u5, u2} D (CategoryTheory.Category.toCategoryStruct.{u5, u2} D _inst_3)) Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.toPrefunctor.{u5, u4, u2, succ u4} D _inst_3 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u2, u4, u5} D _inst_3 _inst_4)) (obj Y))) (Prefunctor.map.{succ u5, succ u4, u2, succ u4} D (CategoryTheory.CategoryStruct.toQuiver.{u5, u2} D (CategoryTheory.Category.toCategoryStruct.{u5, u2} D _inst_3)) Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.toPrefunctor.{u5, u4, u2, succ u4} D _inst_3 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u2, u4, u5} D _inst_3 _inst_4)) (obj X) (obj Y) (map X Y f)) (Quiver.Hom.{succ u4, succ u4} Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (Prefunctor.obj.{succ u3, succ u4, u1, succ u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} C (CategoryTheory.Category.toCategoryStruct.{u3, u1} C _inst_1)) Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.toPrefunctor.{u3, u4, u1, succ u4} C _inst_1 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u1, u4, u3} C _inst_1 _inst_2)) X) (Prefunctor.obj.{succ u3, succ u4, u1, succ u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} C (CategoryTheory.Category.toCategoryStruct.{u3, u1} C _inst_1)) Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.toPrefunctor.{u3, u4, u1, succ u4} C _inst_1 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u1, u4, u3} C _inst_1 _inst_2)) Y)) (Prefunctor.map.{succ u3, succ u4, u1, succ u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} C (CategoryTheory.Category.toCategoryStruct.{u3, u1} C _inst_1)) Type.{u4} (CategoryTheory.CategoryStruct.toQuiver.{u4, succ u4} Type.{u4} (CategoryTheory.Category.toCategoryStruct.{u4, succ u4} Type.{u4} CategoryTheory.types.{u4})) (CategoryTheory.Functor.toPrefunctor.{u3, u4, u1, succ u4} C _inst_1 Type.{u4} CategoryTheory.types.{u4} (CategoryTheory.forget.{u1, u4, u3} C _inst_1 _inst_2)) X Y f)) -> (CategoryTheory.HasForget₂.{u1, u2, u4, u3, u5} C D _inst_1 _inst_2 _inst_3 _inst_4))
Case conversion may be inaccurate. Consider using '#align category_theory.has_forget₂.mk' CategoryTheory.HasForget₂.mk'ₓ'. -/
/-- In order to construct a “partially forgetting” functor, we do not need to verify functor laws;
it suffices to ensure that compositions agree with `forget₂ C D ⋙ forget D = forget C`.
-/
def HasForget₂.mk' {C : Type v} {D : Type v'} [Category C] [ConcreteCategory C] [Category D]
    [ConcreteCategory D] (obj : C → D) (h_obj : ∀ X, (forget D).obj (obj X) = (forget C).obj X)
    (map : ∀ {X Y}, (X ⟶ Y) → (obj X ⟶ obj Y))
    (h_map : ∀ {X Y} {f : X ⟶ Y}, HEq ((forget D).map (map f)) ((forget C).map f)) : HasForget₂ C D
    where
  forget₂ := Faithful.div _ _ _ @h_obj _ @h_map
  forget_comp := by apply faithful.div_comp
#align category_theory.has_forget₂.mk' CategoryTheory.HasForget₂.mk'

#print CategoryTheory.hasForgetToType /-
/-- Every forgetful functor factors through the identity functor. This is not a global instance as
    it is prone to creating type class resolution loops. -/
def hasForgetToType (C : Type v) [Category C] [ConcreteCategory C] : HasForget₂ C (Type u)
    where
  forget₂ := forget C
  forget_comp := Functor.comp_id _
#align category_theory.has_forget_to_Type CategoryTheory.hasForgetToType
-/

end CategoryTheory