/-
Copyright (c) 2020 David Wärn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn

! This file was ported from Lean 3 source module category_theory.quotient
! 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.NaturalIsomorphism
import Mathbin.CategoryTheory.EqToHom

/-!
# Quotient category

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

Constructs the quotient of a category by an arbitrary family of relations on its hom-sets,
by introducing a type synonym for the objects, and identifying homs as necessary.

This is analogous to 'the quotient of a group by the normal closure of a subset', rather
than 'the quotient of a group by a normal subgroup'. When taking the quotient by a congruence
relation, `functor_map_eq_iff` says that no unnecessary identifications have been made.
-/

#print HomRel /-
/-- A `hom_rel` on `C` consists of a relation on every hom-set. -/
def HomRel (C) [Quiver C] :=
  ∀ ⦃X Y : C⦄, (X ⟶ Y) → (X ⟶ Y) → Prop deriving Inhabited
#align hom_rel HomRel
-/

namespace CategoryTheory

variable {C : Type _} [Category C] (r : HomRel C)

include r

#print CategoryTheory.Congruence /-
/-- A `hom_rel` is a congruence when it's an equivalence on every hom-set, and it can be composed
from left and right. -/
class Congruence : Prop where
  IsEquiv : ∀ {X Y}, IsEquiv _ (@r X Y)
  compLeft : ∀ {X Y Z} (f : X ⟶ Y) {g g' : Y ⟶ Z}, r g g' → r (f ≫ g) (f ≫ g')
  compRight : ∀ {X Y Z} {f f' : X ⟶ Y} (g : Y ⟶ Z), r f f' → r (f ≫ g) (f' ≫ g)
#align category_theory.congruence CategoryTheory.Congruence
-/

attribute [instance] congruence.is_equiv

#print CategoryTheory.Quotient /-
/-- A type synonym for `C`, thought of as the objects of the quotient category. -/
@[ext]
structure Quotient where
  as : C
#align category_theory.quotient CategoryTheory.Quotient
-/

instance [Inhabited C] : Inhabited (Quotient r) :=
  ⟨{ as := default }⟩

namespace Quotient

#print CategoryTheory.Quotient.CompClosure /-
/-- Generates the closure of a family of relations w.r.t. composition from left and right. -/
inductive CompClosure ⦃s t : C⦄ : (s ⟶ t) → (s ⟶ t) → Prop
  |
  intro {a b} (f : s ⟶ a) (m₁ m₂ : a ⟶ b) (g : b ⟶ t) (h : r m₁ m₂) :
    comp_closure (f ≫ m₁ ≫ g) (f ≫ m₂ ≫ g)
#align category_theory.quotient.comp_closure CategoryTheory.Quotient.CompClosure
-/

#print CategoryTheory.Quotient.CompClosure.of /-
theorem CompClosure.of {a b} (m₁ m₂ : a ⟶ b) (h : r m₁ m₂) : CompClosure r m₁ m₂ := by
  simpa using comp_closure.intro (𝟙 _) m₁ m₂ (𝟙 _) h
#align category_theory.quotient.comp_closure.of CategoryTheory.Quotient.CompClosure.of
-/

#print CategoryTheory.Quotient.comp_left /-
theorem comp_left {a b c : C} (f : a ⟶ b) :
    ∀ (g₁ g₂ : b ⟶ c) (h : CompClosure r g₁ g₂), CompClosure r (f ≫ g₁) (f ≫ g₂)
  | _, _, ⟨x, m₁, m₂, y, h⟩ => by simpa using comp_closure.intro (f ≫ x) m₁ m₂ y h
#align category_theory.quotient.comp_left CategoryTheory.Quotient.comp_left
-/

#print CategoryTheory.Quotient.comp_right /-
theorem comp_right {a b c : C} (g : b ⟶ c) :
    ∀ (f₁ f₂ : a ⟶ b) (h : CompClosure r f₁ f₂), CompClosure r (f₁ ≫ g) (f₂ ≫ g)
  | _, _, ⟨x, m₁, m₂, y, h⟩ => by simpa using comp_closure.intro x m₁ m₂ (y ≫ g) h
#align category_theory.quotient.comp_right CategoryTheory.Quotient.comp_right
-/

#print CategoryTheory.Quotient.Hom /-
/-- Hom-sets of the quotient category. -/
def Hom (s t : Quotient r) :=
  Quot <| @CompClosure C _ r s.as t.as
#align category_theory.quotient.hom CategoryTheory.Quotient.Hom
-/

instance (a : Quotient r) : Inhabited (Hom r a a) :=
  ⟨Quot.mk _ (𝟙 a.as)⟩

#print CategoryTheory.Quotient.comp /-
/-- Composition in the quotient category. -/
def comp ⦃a b c : Quotient r⦄ : Hom r a b → Hom r b c → Hom r a c := fun hf hg =>
  Quot.liftOn hf
    (fun f =>
      Quot.liftOn hg (fun g => Quot.mk _ (f ≫ g)) fun g₁ g₂ h =>
        Quot.sound <| comp_left r f g₁ g₂ h)
    fun f₁ f₂ h => Quot.inductionOn hg fun g => Quot.sound <| comp_right r g f₁ f₂ h
#align category_theory.quotient.comp CategoryTheory.Quotient.comp
-/

/- warning: category_theory.quotient.comp_mk -> CategoryTheory.Quotient.comp_mk is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {a : CategoryTheory.Quotient.{u1, u2} C _inst_1 r} {b : CategoryTheory.Quotient.{u1, u2} C _inst_1 r} {c : CategoryTheory.Quotient.{u1, u2} C _inst_1 r} (f : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r a) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r b)) (g : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r b) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r c)), Eq.{succ u2} (CategoryTheory.Quotient.Hom.{u1, u2} C _inst_1 r a c) (CategoryTheory.Quotient.comp.{u1, u2} C _inst_1 r a b c (Quot.mk.{succ u2} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r a) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r b)) (CategoryTheory.Quotient.CompClosure.{u1, u2} C _inst_1 r (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r a) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r b)) f) (Quot.mk.{succ u2} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r b) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r c)) (CategoryTheory.Quotient.CompClosure.{u1, u2} C _inst_1 r (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r b) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r c)) g)) (Quot.mk.{succ u2} (Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r a) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r c)) (CategoryTheory.Quotient.CompClosure.{u1, u2} C _inst_1 r (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r a) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r c)) (CategoryTheory.CategoryStruct.comp.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r a) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r b) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r c) f g))
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] (r : HomRel.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) {a : CategoryTheory.Quotient.{u2, u1} C _inst_1 r} {b : CategoryTheory.Quotient.{u2, u1} C _inst_1 r} {c : CategoryTheory.Quotient.{u2, u1} C _inst_1 r} (f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r a) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r b)) (g : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r b) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r c)), Eq.{succ u1} (CategoryTheory.Quotient.Hom.{u2, u1} C _inst_1 r a c) (CategoryTheory.Quotient.comp.{u2, u1} C _inst_1 r a b c (Quot.mk.{succ u1} (Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r a) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r b)) (CategoryTheory.Quotient.CompClosure.{u2, u1} C _inst_1 r (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r a) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r b)) f) (Quot.mk.{succ u1} (Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r b) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r c)) (CategoryTheory.Quotient.CompClosure.{u2, u1} C _inst_1 r (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r b) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r c)) g)) (Quot.mk.{succ u1} (Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r a) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r c)) (CategoryTheory.Quotient.CompClosure.{u2, u1} C _inst_1 r (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r a) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r c)) (CategoryTheory.CategoryStruct.comp.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r a) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r b) (CategoryTheory.Quotient.as.{u2, u1} C _inst_1 r c) f g))
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.comp_mk CategoryTheory.Quotient.comp_mkₓ'. -/
@[simp]
theorem comp_mk {a b c : Quotient r} (f : a.as ⟶ b.as) (g : b.as ⟶ c.as) :
    comp r (Quot.mk _ f) (Quot.mk _ g) = Quot.mk _ (f ≫ g) :=
  rfl
#align category_theory.quotient.comp_mk CategoryTheory.Quotient.comp_mk

#print CategoryTheory.Quotient.category /-
instance category : Category (Quotient r)
    where
  Hom := Hom r
  id a := Quot.mk _ (𝟙 a.as)
  comp := comp r
#align category_theory.quotient.category CategoryTheory.Quotient.category
-/

#print CategoryTheory.Quotient.functor /-
/-- The functor from a category to its quotient. -/
@[simps]
def functor : C ⥤ Quotient r where
  obj a := { as := a }
  map _ _ f := Quot.mk _ f
#align category_theory.quotient.functor CategoryTheory.Quotient.functor
-/

noncomputable instance : Full (functor r) where preimage X Y f := Quot.out f

instance : EssSurj (functor r)
    where mem_essImage Y :=
    ⟨Y.as,
      ⟨eqToIso
          (by
            ext
            rfl)⟩⟩

/- warning: category_theory.quotient.induction -> CategoryTheory.Quotient.induction is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {P : forall {a : CategoryTheory.Quotient.{u1, u2} C _inst_1 r} {b : CategoryTheory.Quotient.{u1, u2} C _inst_1 r}, (Quiver.Hom.{succ u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) a b) -> Prop}, (forall {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), P (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) x) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) y) (CategoryTheory.Functor.map.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) x y f)) -> (forall {a : CategoryTheory.Quotient.{u1, u2} C _inst_1 r} {b : CategoryTheory.Quotient.{u1, u2} C _inst_1 r} (f : Quiver.Hom.{succ u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) a b), P a b f)
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] (r : HomRel.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) {P : forall {a : CategoryTheory.Quotient.{u2, u1} C _inst_1 r} {b : CategoryTheory.Quotient.{u2, u1} C _inst_1 r}, (Quiver.Hom.{succ u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) a b) -> Prop}, (forall {x : C} {y : C} (f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) x y), P (Prefunctor.obj.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_1 (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.functor.{u2, u1} C _inst_1 r)) x) (Prefunctor.obj.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_1 (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.functor.{u2, u1} C _inst_1 r)) y) (Prefunctor.map.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_1 (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.functor.{u2, u1} C _inst_1 r)) x y f)) -> (forall {a : CategoryTheory.Quotient.{u2, u1} C _inst_1 r} {b : CategoryTheory.Quotient.{u2, u1} C _inst_1 r} (f : Quiver.Hom.{succ u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) a b), P a b f)
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.induction CategoryTheory.Quotient.inductionₓ'. -/
protected theorem induction {P : ∀ {a b : Quotient r}, (a ⟶ b) → Prop}
    (h : ∀ {x y : C} (f : x ⟶ y), P ((functor r).map f)) : ∀ {a b : Quotient r} (f : a ⟶ b), P f :=
  by
  rintro ⟨x⟩ ⟨y⟩ ⟨f⟩
  exact h f
#align category_theory.quotient.induction CategoryTheory.Quotient.induction

/- warning: category_theory.quotient.sound -> CategoryTheory.Quotient.sound is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {a : C} {b : C} {f₁ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) a b} {f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) a b}, (r a b f₁ f₂) -> (Eq.{succ u2} (Quiver.Hom.{succ u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) a) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) b)) (CategoryTheory.Functor.map.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) a b f₁) (CategoryTheory.Functor.map.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) a b f₂))
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {a : C} {b : C} {f₁ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) a b} {f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) a b}, (r a b f₁ f₂) -> (Eq.{succ u2} (Quiver.Hom.{succ u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) (Prefunctor.obj.{succ u2, succ u2, u1, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r)) a) (Prefunctor.obj.{succ u2, succ u2, u1, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r)) b)) (Prefunctor.map.{succ u2, succ u2, u1, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r)) a b f₁) (Prefunctor.map.{succ u2, succ u2, u1, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r)) a b f₂))
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.sound CategoryTheory.Quotient.soundₓ'. -/
protected theorem sound {a b : C} {f₁ f₂ : a ⟶ b} (h : r f₁ f₂) :
    (functor r).map f₁ = (functor r).map f₂ := by
  simpa using Quot.sound (comp_closure.intro (𝟙 a) f₁ f₂ (𝟙 b) h)
#align category_theory.quotient.sound CategoryTheory.Quotient.sound

/- warning: category_theory.quotient.functor_map_eq_iff -> CategoryTheory.Quotient.functor_map_eq_iff is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) [_inst_2 : CategoryTheory.Congruence.{u1, u2} C _inst_1 r] {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) (f' : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) X Y), Iff (Eq.{succ u2} (Quiver.Hom.{succ u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u2, u1} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r))) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) X) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) Y)) (CategoryTheory.Functor.map.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) X Y f) (CategoryTheory.Functor.map.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) X Y f')) (r X Y f f')
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u1, u2} C] (r : HomRel.{u2, succ u1} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1))) [_inst_2 : CategoryTheory.Congruence.{u2, u1} C _inst_1 r] {X : C} {Y : C} (f : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y) (f' : Quiver.Hom.{succ u1, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) X Y), Iff (Eq.{succ u1} (Quiver.Hom.{succ u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) (Prefunctor.obj.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_1 (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.functor.{u2, u1} C _inst_1 r)) X) (Prefunctor.obj.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_1 (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.functor.{u2, u1} C _inst_1 r)) Y)) (Prefunctor.map.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_1 (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.functor.{u2, u1} C _inst_1 r)) X Y f) (Prefunctor.map.{succ u1, succ u1, u2, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} C (CategoryTheory.Category.toCategoryStruct.{u1, u2} C _inst_1)) (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u1, u2} (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u1, u1, u2, u2} C _inst_1 (CategoryTheory.Quotient.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u1} C _inst_1 r) (CategoryTheory.Quotient.functor.{u2, u1} C _inst_1 r)) X Y f')) (r X Y f f')
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.functor_map_eq_iff CategoryTheory.Quotient.functor_map_eq_iffₓ'. -/
theorem functor_map_eq_iff [Congruence r] {X Y : C} (f f' : X ⟶ Y) :
    (functor r).map f = (functor r).map f' ↔ r f f' :=
  by
  constructor
  · erw [Quot.eq]
    intro h
    induction' h with m m' hm
    · cases hm
      apply congruence.comp_left
      apply congruence.comp_right
      assumption
    · apply refl
    · apply symm
      assumption
    · apply trans <;> assumption
  · apply Quotient.sound
#align category_theory.quotient.functor_map_eq_iff CategoryTheory.Quotient.functor_map_eq_iff

variable {D : Type _} [Category D] (F : C ⥤ D)
  (H : ∀ (x y : C) (f₁ f₂ : x ⟶ y), r f₁ f₂ → F.map f₁ = F.map f₂)

include H

/- warning: category_theory.quotient.lift -> CategoryTheory.Quotient.lift is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2), (forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F y)) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₁) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₂))) -> (CategoryTheory.Functor.{u2, u4, u1, u3} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2)
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2), (forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) y)) (Prefunctor.map.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x y f₁) (Prefunctor.map.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x y f₂))) -> (CategoryTheory.Functor.{u2, u4, u1, u3} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2)
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.lift CategoryTheory.Quotient.liftₓ'. -/
/-- The induced functor on the quotient category. -/
@[simps]
def lift : Quotient r ⥤ D where
  obj a := F.obj a.as
  map a b hf :=
    Quot.liftOn hf (fun f => F.map f)
      (by
        rintro _ _ ⟨_, _, _, _, h⟩
        simp [H _ _ _ _ h])
  map_id' a := F.map_id a.as
  map_comp' := by
    rintro a b c ⟨f⟩ ⟨g⟩
    exact F.map_comp f g
#align category_theory.quotient.lift CategoryTheory.Quotient.lift

/- warning: category_theory.quotient.lift_spec -> CategoryTheory.Quotient.lift_spec is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F y)) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₁) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₂))), Eq.{succ (max u2 u4 u1 u3)} (CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F
but is expected to have type
  forall {C : Type.{u4}} [_inst_1 : CategoryTheory.Category.{u3, u4} C] (r : HomRel.{u4, succ u3} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1))) {D : Type.{u2}} [_inst_2 : CategoryTheory.Category.{u1, u2} D] (F : CategoryTheory.Functor.{u3, u1, u4, u2} C _inst_1 D _inst_2) (H : forall (x : C) (y : C) (f₁ : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) x y) (f₂ : Quiver.Hom.{succ u3, u4} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u1} (Quiver.Hom.{succ u1, u2} D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) x) (Prefunctor.obj.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) y)) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) x y f₁) (Prefunctor.map.{succ u3, succ u1, u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u3, u4} C (CategoryTheory.Category.toCategoryStruct.{u3, u4} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u1, u2} D (CategoryTheory.Category.toCategoryStruct.{u1, u2} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u3, u1, u4, u2} C _inst_1 D _inst_2 F) x y f₂))), Eq.{max (max (max (succ u4) (succ u3)) (succ u2)) (succ u1)} (CategoryTheory.Functor.{u3, u1, u4, u2} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u3, u3, u1, u4, u4, u2} C _inst_1 (CategoryTheory.Quotient.{u4, u3} C _inst_1 r) (CategoryTheory.Quotient.category.{u4, u3} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u4, u3} C _inst_1 r) (CategoryTheory.Quotient.lift.{u4, u3, u2, u1} C _inst_1 r D _inst_2 F H)) F
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.lift_spec CategoryTheory.Quotient.lift_specₓ'. -/
theorem lift_spec : functor r ⋙ lift r F H = F :=
  by
  apply Functor.ext; rotate_left
  · rintro X
    rfl
  · rintro X Y f
    simp
#align category_theory.quotient.lift_spec CategoryTheory.Quotient.lift_spec

/- warning: category_theory.quotient.lift_unique -> CategoryTheory.Quotient.lift_unique is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F y)) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₁) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₂))) (Φ : CategoryTheory.Functor.{u2, u4, u1, u3} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2), (Eq.{succ (max u2 u4 u1 u3)} (CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) Φ) F) -> (Eq.{succ (max u2 u4 u1 u3)} (CategoryTheory.Functor.{u2, u4, u1, u3} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2) Φ (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H))
but is expected to have type
  forall {C : Type.{u2}} [_inst_1 : CategoryTheory.Category.{u4, u2} C] (r : HomRel.{u2, succ u4} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u2} C (CategoryTheory.Category.toCategoryStruct.{u4, u2} C _inst_1))) {D : Type.{u1}} [_inst_2 : CategoryTheory.Category.{u3, u1} D] (F : CategoryTheory.Functor.{u4, u3, u2, u1} C _inst_1 D _inst_2) (H : forall (x : C) (y : C) (f₁ : Quiver.Hom.{succ u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u2} C (CategoryTheory.Category.toCategoryStruct.{u4, u2} C _inst_1)) x y) (f₂ : Quiver.Hom.{succ u4, u2} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u2} C (CategoryTheory.Category.toCategoryStruct.{u4, u2} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u3} (Quiver.Hom.{succ u3, u1} D (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} D (CategoryTheory.Category.toCategoryStruct.{u3, u1} D _inst_2)) (Prefunctor.obj.{succ u4, succ u3, u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u2} C (CategoryTheory.Category.toCategoryStruct.{u4, u2} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} D (CategoryTheory.Category.toCategoryStruct.{u3, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u3, u2, u1} C _inst_1 D _inst_2 F) x) (Prefunctor.obj.{succ u4, succ u3, u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u2} C (CategoryTheory.Category.toCategoryStruct.{u4, u2} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} D (CategoryTheory.Category.toCategoryStruct.{u3, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u3, u2, u1} C _inst_1 D _inst_2 F) y)) (Prefunctor.map.{succ u4, succ u3, u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u2} C (CategoryTheory.Category.toCategoryStruct.{u4, u2} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} D (CategoryTheory.Category.toCategoryStruct.{u3, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u3, u2, u1} C _inst_1 D _inst_2 F) x y f₁) (Prefunctor.map.{succ u4, succ u3, u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u2} C (CategoryTheory.Category.toCategoryStruct.{u4, u2} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u3, u1} D (CategoryTheory.Category.toCategoryStruct.{u3, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u3, u2, u1} C _inst_1 D _inst_2 F) x y f₂))) (Φ : CategoryTheory.Functor.{u4, u3, u2, u1} (CategoryTheory.Quotient.{u2, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u4} C _inst_1 r) D _inst_2), (Eq.{max (max (max (succ u2) (succ u4)) (succ u1)) (succ u3)} (CategoryTheory.Functor.{u4, u3, u2, u1} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u4, u4, u3, u2, u2, u1} C _inst_1 (CategoryTheory.Quotient.{u2, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u4} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u2, u4} C _inst_1 r) Φ) F) -> (Eq.{max (max (max (succ u2) (succ u4)) (succ u1)) (succ u3)} (CategoryTheory.Functor.{u4, u3, u2, u1} (CategoryTheory.Quotient.{u2, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u2, u4} C _inst_1 r) D _inst_2) Φ (CategoryTheory.Quotient.lift.{u2, u4, u1, u3} C _inst_1 r D _inst_2 F H))
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.lift_unique CategoryTheory.Quotient.lift_uniqueₓ'. -/
theorem lift_unique (Φ : Quotient r ⥤ D) (hΦ : functor r ⋙ Φ = F) : Φ = lift r F H :=
  by
  subst_vars
  apply functor.hext
  · rintro X
    dsimp [lift, Functor]
    congr
    ext
    rfl
  · rintro X Y f
    dsimp [lift, Functor]
    apply Quot.inductionOn f
    rintro ff
    simp only [Quot.liftOn_mk, functor.comp_map]
    congr <;> ext <;> rfl
#align category_theory.quotient.lift_unique CategoryTheory.Quotient.lift_unique

/- warning: category_theory.quotient.lift.is_lift -> CategoryTheory.Quotient.lift.isLift is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F y)) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₁) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₂))), CategoryTheory.Iso.{max u1 u4, max u2 u4 u1 u3} (CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.category.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) y)) (Prefunctor.map.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x y f₁) (Prefunctor.map.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x y f₂))), CategoryTheory.Iso.{max u1 u4, max (max (max u3 u1) u4) u2} (CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.category.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.lift.is_lift CategoryTheory.Quotient.lift.isLiftₓ'. -/
/-- The original functor factors through the induced functor. -/
def lift.isLift : functor r ⋙ lift r F H ≅ F :=
  NatIso.ofComponents (fun X => Iso.refl _) (by tidy)
#align category_theory.quotient.lift.is_lift CategoryTheory.Quotient.lift.isLift

/- warning: category_theory.quotient.lift.is_lift_hom -> CategoryTheory.Quotient.lift.isLift_hom is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F y)) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₁) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₂))) (X : C), Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) X) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F X)) (CategoryTheory.NatTrans.app.{u2, u4, u1, u3} C _inst_1 D _inst_2 (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F (CategoryTheory.Iso.hom.{max u1 u4, max u2 u4 u1 u3} (CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.category.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F (CategoryTheory.Quotient.lift.isLift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) X) (CategoryTheory.CategoryStruct.id.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F X))
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) y)) (Prefunctor.map.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x y f₁) (Prefunctor.map.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x y f₂))) (X : C), Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H))) X) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) X)) (CategoryTheory.NatTrans.app.{u2, u4, u1, u3} C _inst_1 D _inst_2 (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F (CategoryTheory.Iso.hom.{max u1 u4, max (max (max u1 u2) u3) u4} (CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.category.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F (CategoryTheory.Quotient.lift.isLift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) X) (CategoryTheory.CategoryStruct.id.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) X))
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.lift.is_lift_hom CategoryTheory.Quotient.lift.isLift_homₓ'. -/
@[simp]
theorem lift.isLift_hom (X : C) : (lift.isLift r F H).Hom.app X = 𝟙 (F.obj X) :=
  rfl
#align category_theory.quotient.lift.is_lift_hom CategoryTheory.Quotient.lift.isLift_hom

/- warning: category_theory.quotient.lift.is_lift_inv -> CategoryTheory.Quotient.lift.isLift_inv is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F y)) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₁) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₂))) (X : C), Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F X) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) X)) (CategoryTheory.NatTrans.app.{u2, u4, u1, u3} C _inst_1 D _inst_2 F (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) (CategoryTheory.Iso.inv.{max u1 u4, max u2 u4 u1 u3} (CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.category.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F (CategoryTheory.Quotient.lift.isLift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) X) (CategoryTheory.CategoryStruct.id.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F X))
but is expected to have type
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) y)) (Prefunctor.map.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x y f₁) (Prefunctor.map.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) x y f₂))) (X : C), Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) X) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H))) X)) (CategoryTheory.NatTrans.app.{u2, u4, u1, u3} C _inst_1 D _inst_2 F (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) (CategoryTheory.Iso.inv.{max u1 u4, max (max (max u1 u2) u3) u4} (CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.category.{u2, u4, u1, u3} C _inst_1 D _inst_2) (CategoryTheory.Functor.comp.{u2, u2, u4, u1, u1, u3} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) F (CategoryTheory.Quotient.lift.isLift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H)) X) (CategoryTheory.CategoryStruct.id.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2) (Prefunctor.obj.{succ u2, succ u4, u1, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u2, u4, u1, u3} C _inst_1 D _inst_2 F) X))
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.lift.is_lift_inv CategoryTheory.Quotient.lift.isLift_invₓ'. -/
@[simp]
theorem lift.isLift_inv (X : C) : (lift.isLift r F H).inv.app X = 𝟙 (F.obj X) :=
  rfl
#align category_theory.quotient.lift.is_lift_inv CategoryTheory.Quotient.lift.isLift_inv

/- warning: category_theory.quotient.lift_map_functor_map -> CategoryTheory.Quotient.lift_map_functor_map is a dubious translation:
lean 3 declaration is
  forall {C : Type.{u1}} [_inst_1 : CategoryTheory.Category.{u2, u1} C] (r : HomRel.{u1, succ u2} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1))) {D : Type.{u3}} [_inst_2 : CategoryTheory.Category.{u4, u3} D] (F : CategoryTheory.Functor.{u2, u4, u1, u3} C _inst_1 D _inst_2) (H : forall (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) (f₂ : Quiver.Hom.{succ u2, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} C (CategoryTheory.Category.toCategoryStruct.{u2, u1} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} C _inst_1 D _inst_2 F y)) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₁) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F x y f₂))) {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 u4} (Quiver.Hom.{succ u4, u3} D (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} D (CategoryTheory.Category.toCategoryStruct.{u4, u3} D _inst_2)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) X)) (CategoryTheory.Functor.obj.{u2, u4, u1, u3} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) Y))) (CategoryTheory.Functor.map.{u2, u4, u1, u3} (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.lift.{u1, u2, u3, u4} C _inst_1 r D _inst_2 F H) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) X) (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) Y) (CategoryTheory.Functor.map.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) X Y f)) (CategoryTheory.Functor.map.{u2, u4, u1, u3} C _inst_1 D _inst_2 F (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) X)) (CategoryTheory.Quotient.as.{u1, u2} C _inst_1 r (CategoryTheory.Functor.obj.{u2, u2, u1, u1} C _inst_1 (CategoryTheory.Quotient.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.category.{u1, u2} C _inst_1 r) (CategoryTheory.Quotient.functor.{u1, u2} C _inst_1 r) Y)) f)
but is expected to have type
  forall {C : Type.{u3}} [_inst_1 : CategoryTheory.Category.{u4, u3} C] (r : HomRel.{u3, succ u4} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1))) {D : Type.{u1}} [_inst_2 : CategoryTheory.Category.{u2, u1} D] (F : CategoryTheory.Functor.{u4, u2, u3, u1} C _inst_1 D _inst_2) (H : forall (x : C) (y : C) (f₁ : Quiver.Hom.{succ u4, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) x y) (f₂ : Quiver.Hom.{succ u4, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) x y), (r x y f₁ f₂) -> (Eq.{succ u2} (Quiver.Hom.{succ u2, u1} D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (Prefunctor.obj.{succ u4, succ u2, u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u2, u3, u1} C _inst_1 D _inst_2 F) x) (Prefunctor.obj.{succ u4, succ u2, u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u2, u3, u1} C _inst_1 D _inst_2 F) y)) (Prefunctor.map.{succ u4, succ u2, u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u2, u3, u1} C _inst_1 D _inst_2 F) x y f₁) (Prefunctor.map.{succ u4, succ u2, u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u2, u3, u1} C _inst_1 D _inst_2 F) x y f₂))) {X : C} {Y : C} (f : Quiver.Hom.{succ u4, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) X Y), Eq.{succ u2} (Quiver.Hom.{succ u2, u1} D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (Prefunctor.obj.{succ u4, succ u2, u3, u1} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r))) D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u2, u3, u1} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.lift.{u3, u4, u1, u2} C _inst_1 r D _inst_2 F H)) (Prefunctor.obj.{succ u4, succ u4, u3, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u4, u4, u3, u3} C _inst_1 (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.functor.{u3, u4} C _inst_1 r)) X)) (Prefunctor.obj.{succ u4, succ u2, u3, u1} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r))) D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u2, u3, u1} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.lift.{u3, u4, u1, u2} C _inst_1 r D _inst_2 F H)) (Prefunctor.obj.{succ u4, succ u4, u3, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u4, u4, u3, u3} C _inst_1 (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.functor.{u3, u4} C _inst_1 r)) Y))) (Prefunctor.map.{succ u4, succ u2, u3, u1} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r))) D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u2, u3, u1} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r) D _inst_2 (CategoryTheory.Quotient.lift.{u3, u4, u1, u2} C _inst_1 r D _inst_2 F H)) (Prefunctor.obj.{succ u4, succ u4, u3, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u4, u4, u3, u3} C _inst_1 (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.functor.{u3, u4} C _inst_1 r)) X) (Prefunctor.obj.{succ u4, succ u4, u3, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u4, u4, u3, u3} C _inst_1 (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.functor.{u3, u4} C _inst_1 r)) Y) (Prefunctor.map.{succ u4, succ u4, u3, u3} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Category.toCategoryStruct.{u4, u3} (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r))) (CategoryTheory.Functor.toPrefunctor.{u4, u4, u3, u3} C _inst_1 (CategoryTheory.Quotient.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.category.{u3, u4} C _inst_1 r) (CategoryTheory.Quotient.functor.{u3, u4} C _inst_1 r)) X Y f)) (Prefunctor.map.{succ u4, succ u2, u3, u1} C (CategoryTheory.CategoryStruct.toQuiver.{u4, u3} C (CategoryTheory.Category.toCategoryStruct.{u4, u3} C _inst_1)) D (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} D (CategoryTheory.Category.toCategoryStruct.{u2, u1} D _inst_2)) (CategoryTheory.Functor.toPrefunctor.{u4, u2, u3, u1} C _inst_1 D _inst_2 F) X Y f)
Case conversion may be inaccurate. Consider using '#align category_theory.quotient.lift_map_functor_map CategoryTheory.Quotient.lift_map_functor_mapₓ'. -/
theorem lift_map_functor_map {X Y : C} (f : X ⟶ Y) :
    (lift r F H).map ((functor r).map f) = F.map f :=
  by
  rw [← nat_iso.naturality_1 (lift.is_lift r F H)]
  dsimp
  simp
#align category_theory.quotient.lift_map_functor_map CategoryTheory.Quotient.lift_map_functor_map

end Quotient

end CategoryTheory


/-
Copyright (c) 2019 Scott Morrison. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Scott Morrison
-/
import category_theory.limits.shapes.binary_products
import category_theory.limits.shapes.finite_limits
import category_theory.limits.shapes.products
import category_theory.limits.shapes.terminal

/-!
# Categories with finite (co)products

Typeclasses representing categories with (co)products over finite indexing types.
-/

universes w v u

open category_theory
namespace category_theory.limits

variables (C : Type u) [category.{v} C]

/--
A category has finite products if there is a chosen limit for every diagram
with shape `discrete J`, where we have `[decidable_eq J]` and `[fintype J]`.
-/
-- We can't simply make this an abbreviation, as we do with other `has_Xs` limits typeclasses,
-- because of https://github.com/leanprover-community/lean/issues/429
class has_finite_products : Prop :=
(out (J : Type v) [decidable_eq J] [fintype J] : has_limits_of_shape (discrete J) C)

instance has_limits_of_shape_discrete
  (J : Type v) [fintype J] [has_finite_products C] :
  has_limits_of_shape (discrete J) C :=
by { haveI := @has_finite_products.out C _ _ J (classical.dec_eq _), apply_instance }

/-- If `C` has finite limits then it has finite products. -/
@[priority 10]
instance has_finite_products_of_has_finite_limits [has_finite_limits C] : has_finite_products C :=
⟨λ J 𝒥₁ 𝒥₂, by { resetI, apply_instance }⟩

instance has_fintype_products [has_finite_products C] (ι : Type w) [fintype ι] :
  has_limits_of_shape (discrete ι) C :=
has_limits_of_shape_of_equivalence
  (discrete.equivalence
    ((show ulift.{v} (fin (fintype.card ι)) ≃ fin (fintype.card ι), by tidy).trans
      (fintype.equiv_fin ι).symm))

/-- We can now write this for powers. -/
noncomputable example [has_finite_products C] (X : C) : C := ∏ (λ (i : fin 5), X)

/--
If a category has all products then in particular it has finite products.
-/
lemma has_finite_products_of_has_products [has_products C] : has_finite_products C :=
⟨by apply_instance⟩

/--
A category has finite coproducts if there is a chosen colimit for every diagram
with shape `discrete J`, where we have `[decidable_eq J]` and `[fintype J]`.
-/
class has_finite_coproducts : Prop :=
(out (J : Type v) [decidable_eq J] [fintype J] : has_colimits_of_shape (discrete J) C)

attribute [class] has_finite_coproducts

instance has_colimits_of_shape_discrete
  (J : Type v) [fintype J] [has_finite_coproducts C] :
  has_colimits_of_shape (discrete J) C :=
by { haveI := @has_finite_coproducts.out C _ _ J (classical.dec_eq _), apply_instance }

/-- If `C` has finite colimits then it has finite coproducts. -/
@[priority 10]
instance has_finite_coproducts_of_has_finite_colimits [has_finite_colimits C] :
  has_finite_coproducts C :=
⟨λ J 𝒥₁ 𝒥₂, by { resetI, apply_instance }⟩

instance has_fintype_coproducts [has_finite_coproducts C] (ι : Type w) [fintype ι] :
  has_colimits_of_shape (discrete ι) C :=
has_colimits_of_shape_of_equivalence
  (discrete.equivalence
    ((show ulift.{v} (fin (fintype.card ι)) ≃ fin (fintype.card ι), by tidy).trans
      (fintype.equiv_fin ι).symm))

/--
If a category has all coproducts then in particular it has finite coproducts.
-/
lemma has_finite_coproducts_of_has_coproducts [has_coproducts C] : has_finite_coproducts C :=
⟨by apply_instance⟩

end category_theory.limits