l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem Exact.lift_comp {P Q R S : C} [Projective P] (h : P ⟶ R) (f : Q ⟶ R) (g : R ⟶ S)
    (hfg : Exact f g) (w : h ≫ g = 0) : Exact.lift h f g hfg w ≫ f = h := by
  simp only [Exact.lift]
  conv_lhs =>
    

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
      (factorThruImageSubobject f) ≫
    f

Next tactic:
congr
@[simp]
theorem Exact.lift_comp {P Q R S : C} [Projective P] (h : P ⟶ R) (f : Q ⟶ R) (g : R ⟶ S)
    (hfg : Exact f g) (w : h ≫ g = 0) : Exact.lift h f g hfg w ≫ f = h := by
  simp only [Exact.lift]
  conv_lhs =>
    congr
    

Proof state:
case a
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
    (factorThruImageSubobject f)
case a
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| f

Next tactic:
rfl
@[simp]
theorem Exact.lift_comp {P Q R S : C} [Projective P] (h : P ⟶ R) (f : Q ⟶ R) (g : R ⟶ S)
    (hfg : Exact f g) (w : h ≫ g = 0) : Exact.lift h f g hfg w ≫ f = h := by
  simp only [Exact.lift]
  conv_lhs =>
    congr
    rfl
    

Proof state:
case a
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
| f

Next tactic:
rw [← imageSubobject_arrow_comp f]
@[simp]
theorem Exact.lift_comp {P Q R S : C} [Projective P] (h : P ⟶ R) (f : Q ⟶ R) (g : R ⟶ S)
    (hfg : Exact f g) (w : h ≫ g = 0) : Exact.lift h f g hfg w ≫ f = h := by
  simp only [Exact.lift]
  conv_lhs =>
    congr
    rfl
    rw [← imageSubobject_arrow_comp f]
  -- See the porting note on `Exact.epi`.
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
⊢ factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
        (factorThruImageSubobject f) ≫
      factorThruImageSubobject f ≫ Subobject.arrow (imageSubobject f) =
    h

Next tactic:
haveI := hfg.epi
@[simp]
theorem Exact.lift_comp {P Q R S : C} [Projective P] (h : P ⟶ R) (f : Q ⟶ R) (g : R ⟶ S)
    (hfg : Exact f g) (w : h ≫ g = 0) : Exact.lift h f g hfg w ≫ f = h := by
  simp only [Exact.lift]
  conv_lhs =>
    congr
    rfl
    rw [← imageSubobject_arrow_comp f]
  -- See the porting note on `Exact.epi`.
  haveI := hfg.epi
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : HasZeroMorphisms C
inst✝² : HasEqualizers C
inst✝¹ : HasImages C
P Q R S : C
inst✝ : Projective P
h : P ⟶ R
f : Q ⟶ R
g : R ⟶ S
hfg : Exact f g
w : h ≫ g = 0
this : Epi (imageToKernel f g (_ : f ≫ g = 0))
⊢ factorThru (factorThru (factorThruKernelSubobject g h w) (imageToKernel f g (_ : f ≫ g = 0)))
        (factorThruImageSubobject f) ≫
      factorThruImageSubobject f ≫ Subobject.arrow (imageSubobject f) =
    h

Next tactic:
rw [← Category.assoc, factorThru_comp, ← imageToKernel_arrow f g, ← Category.assoc,
    CategoryTheory.Projective.factorThru_comp, factorThruKernelSubobject_comp_arrow]
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X Y : limit (F ⋙ objects)
X✝ Y✝ : J
f : X✝ ⟶ Y✝
g : (fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y) X✝
⊢ (fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y) Y✝

Next tactic:
refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
    

Proof state:
case refine'_1
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X Y : limit (F ⋙ objects)
X✝ Y✝ : J
f : X✝ ⟶ Y✝
g : (fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y) X✝
⊢ limit.π (F ⋙ objects) Y✝ X = (F.map f).obj (limit.π (F ⋙ objects) X✝ X)
case refine'_2
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X Y : limit (F ⋙ objects)
X✝ Y✝ : J
f : X✝ ⟶ Y✝
g : (fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y) X✝
⊢ (F.map f).obj (limit.π (F ⋙ objects) X✝ Y) = limit.π (F ⋙ objects) Y✝ Y

Next tactic:
exact (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
    exact (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm
    

Proof state:
case refine'_2
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X Y : limit (F ⋙ objects)
X✝ Y✝ : J
f : X✝ ⟶ Y✝
g : (fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y) X✝
⊢ (F.map f).obj (limit.π (F ⋙ objects) X✝ Y) = limit.π (F ⋙ objects) Y✝ Y

Next tactic:
exact congr_fun (limit.w (F ⋙ Cat.objects) f) Y
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
    exact (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm
    exact congr_fun (limit.w (F ⋙ Cat.objects) f) Y
  map_id X := by
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X✝ Y : limit (F ⋙ objects)
X : J
⊢ { obj := fun j => limit.π (F ⋙ objects) j X✝ ⟶ limit.π (F ⋙ objects) j Y,
          map := fun {X Y_1} f g =>
            eqToHom (_ : limit.π (F ⋙ objects) Y_1 X✝ = (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) X✝) ≫
              (F.map f).map g ≫
                eqToHom (_ : (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
      (𝟙 X) =
    𝟙
      ({ obj := fun j => limit.π (F ⋙ objects) j X✝ ⟶ limit.π (F ⋙ objects) j Y,
            map := fun {X Y_1} f g =>
              eqToHom (_ : limit.π (F ⋙ objects) Y_1 X✝ = (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) X✝) ≫
                (F.map f).map g ≫
                  eqToHom (_ : (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.obj
        X)

Next tactic:
funext f
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
    exact (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm
    exact congr_fun (limit.w (F ⋙ Cat.objects) f) Y
  map_id X := by
    funext f
    

Proof state:
case h
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X✝ Y : limit (F ⋙ objects)
X : J
f :
  { obj := fun j => limit.π (F ⋙ objects) j X✝ ⟶ limit.π (F ⋙ objects) j Y,
        map := fun {X Y_1} f g =>
          eqToHom (_ : limit.π (F ⋙ objects) Y_1 X✝ = (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) X✝) ≫
            (F.map f).map g ≫
              eqToHom (_ : (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.obj
    X
⊢ { obj := fun j => limit.π (F ⋙ objects) j X✝ ⟶ limit.π (F ⋙ objects) j Y,
          map := fun {X Y_1} f g =>
            eqToHom (_ : limit.π (F ⋙ objects) Y_1 X✝ = (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) X✝) ≫
              (F.map f).map g ≫
                eqToHom (_ : (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
      (𝟙 X) f =
    𝟙
      ({ obj := fun j => limit.π (F ⋙ objects) j X✝ ⟶ limit.π (F ⋙ objects) j Y,
            map := fun {X Y_1} f g =>
              eqToHom (_ : limit.π (F ⋙ objects) Y_1 X✝ = (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) X✝) ≫
                (F.map f).map g ≫
                  eqToHom (_ : (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.obj
        X)
      f

Next tactic:
letI : Category (objects.obj (F.obj X)) := (inferInstance : Category (F.obj X))
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
    exact (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm
    exact congr_fun (limit.w (F ⋙ Cat.objects) f) Y
  map_id X := by
    funext f
    letI : Category (objects.obj (F.obj X)) := (inferInstance : Category (F.obj X))
    

Proof state:
case h
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X✝ Y : limit (F ⋙ objects)
X : J
f :
  { obj := fun j => limit.π (F ⋙ objects) j X✝ ⟶ limit.π (F ⋙ objects) j Y,
        map := fun {X Y_1} f g =>
          eqToHom (_ : limit.π (F ⋙ objects) Y_1 X✝ = (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) X✝) ≫
            (F.map f).map g ≫
              eqToHom (_ : (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.obj
    X
this : Category.{v, v} (objects.obj (F.obj X)) := inferInstance
⊢ { obj := fun j => limit.π (F ⋙ objects) j X✝ ⟶ limit.π (F ⋙ objects) j Y,
          map := fun {X Y_1} f g =>
            eqToHom (_ : limit.π (F ⋙ objects) Y_1 X✝ = (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) X✝) ≫
              (F.map f).map g ≫
                eqToHom (_ : (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
      (𝟙 X) f =
    𝟙
      ({ obj := fun j => limit.π (F ⋙ objects) j X✝ ⟶ limit.π (F ⋙ objects) j Y,
            map := fun {X Y_1} f g =>
              eqToHom (_ : limit.π (F ⋙ objects) Y_1 X✝ = (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) X✝) ≫
                (F.map f).map g ≫
                  eqToHom (_ : (limit.π (F ⋙ objects) X ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.obj
        X)
      f

Next tactic:
simp [Functor.congr_hom (F.map_id X) f]
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
    exact (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm
    exact congr_fun (limit.w (F ⋙ Cat.objects) f) Y
  map_id X := by
    funext f
    letI : Category (objects.obj (F.obj X)) := (inferInstance : Category (F.obj X))
    simp [Functor.congr_hom (F.map_id X) f]
  map_comp {_ _ Z} f g := by
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X Y : limit (F ⋙ objects)
x✝¹ x✝ Z : J
f : x✝¹ ⟶ x✝
g : x✝ ⟶ Z
⊢ { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
          map := fun {X_1 Y_1} f g =>
            eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
              (F.map f).map g ≫
                eqToHom (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
      (f ≫ g) =
    { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
            map := fun {X_1 Y_1} f g =>
              eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
                (F.map f).map g ≫
                  eqToHom (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
        f ≫
      { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
            map := fun {X_1 Y_1} f g =>
              eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
                (F.map f).map g ≫
                  eqToHom (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
        g

Next tactic:
funext h
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
    exact (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm
    exact congr_fun (limit.w (F ⋙ Cat.objects) f) Y
  map_id X := by
    funext f
    letI : Category (objects.obj (F.obj X)) := (inferInstance : Category (F.obj X))
    simp [Functor.congr_hom (F.map_id X) f]
  map_comp {_ _ Z} f g := by
    funext h
    

Proof state:
case h
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X Y : limit (F ⋙ objects)
x✝¹ x✝ Z : J
f : x✝¹ ⟶ x✝
g : x✝ ⟶ Z
h :
  { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
        map := fun {X_1 Y_1} f g =>
          eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
            (F.map f).map g ≫
              eqToHom (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.obj
    x✝¹
⊢ { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
          map := fun {X_1 Y_1} f g =>
            eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
              (F.map f).map g ≫
                eqToHom (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
      (f ≫ g) h =
    ({ obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
              map := fun {X_1 Y_1} f g =>
                eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
                  (F.map f).map g ≫
                    eqToHom
                      (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
          f ≫
        { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
              map := fun {X_1 Y_1} f g =>
                eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
                  (F.map f).map g ≫
                    eqToHom
                      (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
          g)
      h

Next tactic:
letI : Category (objects.obj (F.obj Z)) := (inferInstance : Category (F.obj Z))
/-- Auxiliary definition:
the diagram whose limit gives the morphism space between two objects of the limit category. -/
@[simps]
def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : J ⥤ Type v where
  obj j := limit.π (F ⋙ Cat.objects) j X ⟶ limit.π (F ⋙ Cat.objects) j Y
  map f g := by
    refine' eqToHom _ ≫ (F.map f).map g ≫ eqToHom _
    exact (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm
    exact congr_fun (limit.w (F ⋙ Cat.objects) f) Y
  map_id X := by
    funext f
    letI : Category (objects.obj (F.obj X)) := (inferInstance : Category (F.obj X))
    simp [Functor.congr_hom (F.map_id X) f]
  map_comp {_ _ Z} f g := by
    funext h
    letI : Category (objects.obj (F.obj Z)) := (inferInstance : Category (F.obj Z))
    

Proof state:
case h
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X Y : limit (F ⋙ objects)
x✝¹ x✝ Z : J
f : x✝¹ ⟶ x✝
g : x✝ ⟶ Z
h :
  { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
        map := fun {X_1 Y_1} f g =>
          eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
            (F.map f).map g ≫
              eqToHom (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.obj
    x✝¹
this : Category.{v, v} (objects.obj (F.obj Z)) := inferInstance
⊢ { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
          map := fun {X_1 Y_1} f g =>
            eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
              (F.map f).map g ≫
                eqToHom (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
      (f ≫ g) h =
    ({ obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
              map := fun {X_1 Y_1} f g =>
                eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
                  (F.map f).map g ≫
                    eqToHom
                      (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
          f ≫
        { obj := fun j => limit.π (F ⋙ objects) j X ⟶ limit.π (F ⋙ objects) j Y,
              map := fun {X_1 Y_1} f g =>
                eqToHom (_ : limit.π (F ⋙ objects) Y_1 X = (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) X) ≫
                  (F.map f).map g ≫
                    eqToHom
                      (_ : (limit.π (F ⋙ objects) X_1 ≫ (F ⋙ objects).map f) Y = limit.π (F ⋙ objects) Y_1 Y) }.map
          g)
      h

Next tactic:
simp [Functor.congr_hom (F.map_comp f g) h, eqToHom_map]
@[simps]
instance (F : J ⥤ Cat.{v, v}) : Category (limit (F ⋙ Cat.objects)) where
  Hom X Y := limit (homDiagram X Y)
  id X := Types.Limit.mk.{v, v} (homDiagram X X) (fun j => 𝟙 _) fun j j' f => by 

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X : limit (F ⋙ objects)
j j' : J
f : j ⟶ j'
⊢ (homDiagram X X).map f ((fun j => 𝟙 (limit.π (F ⋙ objects) j X)) j) = (fun j => 𝟙 (limit.π (F ⋙ objects) j X)) j'

Next tactic:
simp
@[simps]
instance (F : J ⥤ Cat.{v, v}) : Category (limit (F ⋙ Cat.objects)) where
  Hom X Y := limit (homDiagram X Y)
  id X := Types.Limit.mk.{v, v} (homDiagram X X) (fun j => 𝟙 _) fun j j' f => by simp
  comp {X Y Z} f g :=
    Types.Limit.mk.{v, v} (homDiagram X Z)
      (fun j => limit.π (homDiagram X Y) j f ≫ limit.π (homDiagram Y Z) j g) fun j j' h => by
      

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X Y Z : limit (F ⋙ objects)
f : X ⟶ Y
g : Y ⟶ Z
j j' : J
h : j ⟶ j'
⊢ (homDiagram X Z).map h ((fun j => limit.π (homDiagram X Y) j f ≫ limit.π (homDiagram Y Z) j g) j) =
    (fun j => limit.π (homDiagram X Y) j f ≫ limit.π (homDiagram Y Z) j g) j'

Next tactic:
simp [← congr_fun (limit.w (homDiagram X Y) h) f,
        ← congr_fun (limit.w (homDiagram Y Z) h) g]
@[simps]
instance (F : J ⥤ Cat.{v, v}) : Category (limit (F ⋙ Cat.objects)) where
  Hom X Y := limit (homDiagram X Y)
  id X := Types.Limit.mk.{v, v} (homDiagram X X) (fun j => 𝟙 _) fun j j' f => by simp
  comp {X Y Z} f g :=
    Types.Limit.mk.{v, v} (homDiagram X Z)
      (fun j => limit.π (homDiagram X Y) j f ≫ limit.π (homDiagram Y Z) j g) fun j j' h => by
      simp [← congr_fun (limit.w (homDiagram X Y) h) f,
        ← congr_fun (limit.w (homDiagram Y Z) h) g]
  id_comp _ := by
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X✝ Y✝ : limit (F ⋙ objects)
x✝ : X✝ ⟶ Y✝
⊢ 𝟙 X✝ ≫ x✝ = x✝

Next tactic:
apply Types.limit_ext.{v, v}
@[simps]
instance (F : J ⥤ Cat.{v, v}) : Category (limit (F ⋙ Cat.objects)) where
  Hom X Y := limit (homDiagram X Y)
  id X := Types.Limit.mk.{v, v} (homDiagram X X) (fun j => 𝟙 _) fun j j' f => by simp
  comp {X Y Z} f g :=
    Types.Limit.mk.{v, v} (homDiagram X Z)
      (fun j => limit.π (homDiagram X Y) j f ≫ limit.π (homDiagram Y Z) j g) fun j j' h => by
      simp [← congr_fun (limit.w (homDiagram X Y) h) f,
        ← congr_fun (limit.w (homDiagram Y Z) h) g]
  id_comp _ := by
    apply Types.limit_ext.{v, v}
    

Proof state:
case w
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X✝ Y✝ : limit (F ⋙ objects)
x✝ : X✝ ⟶ Y✝
⊢ ∀ (j : J), limit.π (homDiagram X✝ Y✝) j (𝟙 X✝ ≫ x✝) = limit.π (homDiagram X✝ Y✝) j x✝

Next tactic:
aesop_cat
@[simps]
instance (F : J ⥤ Cat.{v, v}) : Category (limit (F ⋙ Cat.objects)) where
  Hom X Y := limit (homDiagram X Y)
  id X := Types.Limit.mk.{v, v} (homDiagram X X) (fun j => 𝟙 _) fun j j' f => by simp
  comp {X Y Z} f g :=
    Types.Limit.mk.{v, v} (homDiagram X Z)
      (fun j => limit.π (homDiagram X Y) j f ≫ limit.π (homDiagram Y Z) j g) fun j j' h => by
      simp [← congr_fun (limit.w (homDiagram X Y) h) f,
        ← congr_fun (limit.w (homDiagram Y Z) h) g]
  id_comp _ := by
    apply Types.limit_ext.{v, v}
    aesop_cat
  comp_id _ := by
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X✝ Y✝ : limit (F ⋙ objects)
x✝ : X✝ ⟶ Y✝
⊢ x✝ ≫ 𝟙 Y✝ = x✝

Next tactic:
apply Types.limit_ext.{v, v}
@[simps]
instance (F : J ⥤ Cat.{v, v}) : Category (limit (F ⋙ Cat.objects)) where
  Hom X Y := limit (homDiagram X Y)
  id X := Types.Limit.mk.{v, v} (homDiagram X X) (fun j => 𝟙 _) fun j j' f => by simp
  comp {X Y Z} f g :=
    Types.Limit.mk.{v, v} (homDiagram X Z)
      (fun j => limit.π (homDiagram X Y) j f ≫ limit.π (homDiagram Y Z) j g) fun j j' h => by
      simp [← congr_fun (limit.w (homDiagram X Y) h) f,
        ← congr_fun (limit.w (homDiagram Y Z) h) g]
  id_comp _ := by
    apply Types.limit_ext.{v, v}
    aesop_cat
  comp_id _ := by
    apply Types.limit_ext.{v, v}
    

Proof state:
case w
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
X✝ Y✝ : limit (F ⋙ objects)
x✝ : X✝ ⟶ Y✝
⊢ ∀ (j : J), limit.π (homDiagram X✝ Y✝) j (x✝ ≫ 𝟙 Y✝) = limit.π (homDiagram X✝ Y✝) j x✝

Next tactic:
aesop_cat
/-- Auxiliary definition: the universal morphism to the proposed limit cone. -/
@[simps]
def limitConeLift (F : J ⥤ Cat.{v, v}) (s : Cone F) : s.pt ⟶ limitConeX F where
  obj :=
    limit.lift (F ⋙ Cat.objects)
      { pt := s.pt
        π :=
          { app := fun j => (s.π.app j).obj
            naturality := fun _ _ f => Functor.congr_map objects (s.π.naturality f) } }
  map f := by
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
s : Cone F
X✝ Y✝ : ↑s.pt
f : X✝ ⟶ Y✝
⊢ limit.lift (F ⋙ objects) { pt := ↑s.pt, π := NatTrans.mk fun j => (s.π.app j).obj } X✝ ⟶
    limit.lift (F ⋙ objects) { pt := ↑s.pt, π := NatTrans.mk fun j => (s.π.app j).obj } Y✝

Next tactic:
fapply Types.Limit.mk.{v, v}
/-- Auxiliary definition: the universal morphism to the proposed limit cone. -/
@[simps]
def limitConeLift (F : J ⥤ Cat.{v, v}) (s : Cone F) : s.pt ⟶ limitConeX F where
  obj :=
    limit.lift (F ⋙ Cat.objects)
      { pt := s.pt
        π :=
          { app := fun j => (s.π.app j).obj
            naturality := fun _ _ f => Functor.congr_map objects (s.π.naturality f) } }
  map f := by
    fapply Types.Limit.mk.{v, v}
    · 

Proof state:
case x
J : Type v
inst✝ : SmallCategory J
F : J ⥤ Cat
s : Cone F
X✝ Y✝ : ↑s.pt
f : X✝ ⟶ Y✝
⊢ (j : J) →
    (homDiagram (limit.lift (F ⋙ objects) { pt := ↑s.pt, π := NatTrans.mk fun j => (s.π.app j).obj } X✝)
          (limit.lift (F ⋙ objects) { pt := ↑s.pt, π := NatTrans.mk fun j => (s.π.app j).obj } Y✝)).obj
      j

Next tactic:
intro j