l3lab/ntp-mathlib huggingface dataset:
/-- The universal morphism
$\colim_k \lim_j F(j,k) → \lim_j \colim_k F(j, k)$.
-/
noncomputable def colimitLimitToLimitColimit :
    colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) ⟶ limit (curry.obj F ⋙ colim) :=
  limit.lift (curry.obj F ⋙ colim)
    { pt := _
      π :=
        { app := fun j =>
            colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
              { pt := _
                ι :=
                  { app := fun k =>
                      limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫
                        colimit.ι ((curry.obj F).obj j) k
                    naturality := by
                      intro k k' f
                      simp only [Functor.comp_obj, lim_obj, colimit.cocone_x,
                        Functor.const_obj_obj, Functor.comp_map, lim_map,
                        curry_obj_obj_obj, Prod.swap_obj, limMap_π_assoc, curry_obj_map_app,
                        Prod.swap_map, Functor.const_obj_map, Category.comp_id]
                      rw [map_id_left_eq_curry_map, colimit.w] } }
          naturality := by
            

Proof state:
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
⊢ ∀ ⦃X Y : J⦄ (f : X ⟶ Y),
    ((Functor.const J).obj (colimit.cocone (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)).1).map f ≫
        (fun j =>
            colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
              { pt := (colimit.cocone ((curry.obj F).obj j)).1,
                ι :=
                  NatTrans.mk fun k =>
                    limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k })
          Y =
      (fun j =>
            colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
              { pt := (colimit.cocone ((curry.obj F).obj j)).1,
                ι :=
                  NatTrans.mk fun k =>
                    limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k })
          X ≫
        (curry.obj F ⋙ colim).map f

Next tactic:
intro j j' f
/-- The universal morphism
$\colim_k \lim_j F(j,k) → \lim_j \colim_k F(j, k)$.
-/
noncomputable def colimitLimitToLimitColimit :
    colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) ⟶ limit (curry.obj F ⋙ colim) :=
  limit.lift (curry.obj F ⋙ colim)
    { pt := _
      π :=
        { app := fun j =>
            colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
              { pt := _
                ι :=
                  { app := fun k =>
                      limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫
                        colimit.ι ((curry.obj F).obj j) k
                    naturality := by
                      intro k k' f
                      simp only [Functor.comp_obj, lim_obj, colimit.cocone_x,
                        Functor.const_obj_obj, Functor.comp_map, lim_map,
                        curry_obj_obj_obj, Prod.swap_obj, limMap_π_assoc, curry_obj_map_app,
                        Prod.swap_map, Functor.const_obj_map, Category.comp_id]
                      rw [map_id_left_eq_curry_map, colimit.w] } }
          naturality := by
            intro j j' f
            

Proof state:
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
j j' : J
f : j ⟶ j'
⊢ ((Functor.const J).obj (colimit.cocone (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)).1).map f ≫
      (fun j =>
          colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
            { pt := (colimit.cocone ((curry.obj F).obj j)).1,
              ι :=
                NatTrans.mk fun k =>
                  limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k })
        j' =
    (fun j =>
          colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
            { pt := (colimit.cocone ((curry.obj F).obj j)).1,
              ι :=
                NatTrans.mk fun k =>
                  limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k })
        j ≫
      (curry.obj F ⋙ colim).map f

Next tactic:
dsimp
/-- The universal morphism
$\colim_k \lim_j F(j,k) → \lim_j \colim_k F(j, k)$.
-/
noncomputable def colimitLimitToLimitColimit :
    colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) ⟶ limit (curry.obj F ⋙ colim) :=
  limit.lift (curry.obj F ⋙ colim)
    { pt := _
      π :=
        { app := fun j =>
            colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
              { pt := _
                ι :=
                  { app := fun k =>
                      limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫
                        colimit.ι ((curry.obj F).obj j) k
                    naturality := by
                      intro k k' f
                      simp only [Functor.comp_obj, lim_obj, colimit.cocone_x,
                        Functor.const_obj_obj, Functor.comp_map, lim_map,
                        curry_obj_obj_obj, Prod.swap_obj, limMap_π_assoc, curry_obj_map_app,
                        Prod.swap_map, Functor.const_obj_map, Category.comp_id]
                      rw [map_id_left_eq_curry_map, colimit.w] } }
          naturality := by
            intro j j' f
            dsimp
            

Proof state:
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
j j' : J
f : j ⟶ j'
⊢ 𝟙 (colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)) ≫
      colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
        { pt := colimit ((curry.obj F).obj j'),
          ι :=
            NatTrans.mk fun k =>
              limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j' ≫ colimit.ι ((curry.obj F).obj j') k } =
    colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
        { pt := colimit ((curry.obj F).obj j),
          ι :=
            NatTrans.mk fun k =>
              limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k } ≫
      colimMap ((curry.obj F).map f)

Next tactic:
ext k
/-- The universal morphism
$\colim_k \lim_j F(j,k) → \lim_j \colim_k F(j, k)$.
-/
noncomputable def colimitLimitToLimitColimit :
    colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) ⟶ limit (curry.obj F ⋙ colim) :=
  limit.lift (curry.obj F ⋙ colim)
    { pt := _
      π :=
        { app := fun j =>
            colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
              { pt := _
                ι :=
                  { app := fun k =>
                      limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫
                        colimit.ι ((curry.obj F).obj j) k
                    naturality := by
                      intro k k' f
                      simp only [Functor.comp_obj, lim_obj, colimit.cocone_x,
                        Functor.const_obj_obj, Functor.comp_map, lim_map,
                        curry_obj_obj_obj, Prod.swap_obj, limMap_π_assoc, curry_obj_map_app,
                        Prod.swap_map, Functor.const_obj_map, Category.comp_id]
                      rw [map_id_left_eq_curry_map, colimit.w] } }
          naturality := by
            intro j j' f
            dsimp
            ext k
            

Proof state:
case w
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
j j' : J
f : j ⟶ j'
k : K
⊢ colimit.ι (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) k ≫
      𝟙 (colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)) ≫
        colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
          { pt := colimit ((curry.obj F).obj j'),
            ι :=
              NatTrans.mk fun k =>
                limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j' ≫ colimit.ι ((curry.obj F).obj j') k } =
    colimit.ι (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) k ≫
      colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
          { pt := colimit ((curry.obj F).obj j),
            ι :=
              NatTrans.mk fun k =>
                limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k } ≫
        colimMap ((curry.obj F).map f)

Next tactic:
simp only [Functor.comp_obj, lim_obj, Category.id_comp, colimit.ι_desc,
              colimit.ι_desc_assoc, Category.assoc, ι_colimMap,
              curry_obj_obj_obj, curry_obj_map_app]
/-- The universal morphism
$\colim_k \lim_j F(j,k) → \lim_j \colim_k F(j, k)$.
-/
noncomputable def colimitLimitToLimitColimit :
    colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) ⟶ limit (curry.obj F ⋙ colim) :=
  limit.lift (curry.obj F ⋙ colim)
    { pt := _
      π :=
        { app := fun j =>
            colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
              { pt := _
                ι :=
                  { app := fun k =>
                      limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫
                        colimit.ι ((curry.obj F).obj j) k
                    naturality := by
                      intro k k' f
                      simp only [Functor.comp_obj, lim_obj, colimit.cocone_x,
                        Functor.const_obj_obj, Functor.comp_map, lim_map,
                        curry_obj_obj_obj, Prod.swap_obj, limMap_π_assoc, curry_obj_map_app,
                        Prod.swap_map, Functor.const_obj_map, Category.comp_id]
                      rw [map_id_left_eq_curry_map, colimit.w] } }
          naturality := by
            intro j j' f
            dsimp
            ext k
            simp only [Functor.comp_obj, lim_obj, Category.id_comp, colimit.ι_desc,
              colimit.ι_desc_assoc, Category.assoc, ι_colimMap,
              curry_obj_obj_obj, curry_obj_map_app]
            

Proof state:
case w
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
j j' : J
f : j ⟶ j'
k : K
⊢ limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j' ≫ colimit.ι ((curry.obj F).obj j') k =
    limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ F.map (f, 𝟙 k) ≫ colimit.ι ((curry.obj F).obj j') k

Next tactic:
rw [map_id_right_eq_curry_swap_map, limit.w_assoc]
/-- Since `colimit_limit_to_limit_colimit` is a morphism from a colimit to a limit,
this lemma characterises it.
-/
@[reassoc (attr := simp)]
theorem ι_colimitLimitToLimitColimit_π (j) (k) :
    colimit.ι _ k ≫ colimitLimitToLimitColimit F ≫ limit.π _ j =
      limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k := by
  

Proof state:
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
j : J
k : K
⊢ colimit.ι (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) k ≫ colimitLimitToLimitColimit F ≫ limit.π (curry.obj F ⋙ colim) j =
    limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k

Next tactic:
dsimp [colimitLimitToLimitColimit]
/-- Since `colimit_limit_to_limit_colimit` is a morphism from a colimit to a limit,
this lemma characterises it.
-/
@[reassoc (attr := simp)]
theorem ι_colimitLimitToLimitColimit_π (j) (k) :
    colimit.ι _ k ≫ colimitLimitToLimitColimit F ≫ limit.π _ j =
      limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k := by
  dsimp [colimitLimitToLimitColimit]
  

Proof state:
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
j : J
k : K
⊢ colimit.ι (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) k ≫
      limit.lift (curry.obj F ⋙ colim)
          { pt := colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim),
            π :=
              NatTrans.mk fun j =>
                colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
                  { pt := colimit ((curry.obj F).obj j),
                    ι :=
                      NatTrans.mk fun k =>
                        limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k } } ≫
        limit.π (curry.obj F ⋙ colim) j =
    limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k

Next tactic:
simp
@[simp]
theorem ι_colimitLimitToLimitColimit_π_apply (F : J × K ⥤ Type v) (j : J) (k : K) (f) :
    limit.π (curry.obj F ⋙ colim) j
        (colimitLimitToLimitColimit F (colimit.ι (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) k f)) =
      colimit.ι ((curry.obj F).obj j) k (limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j f) := by
  

Proof state:
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F✝ : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
F : J × K ⥤ Type v
j : J
k : K
f : (curry.obj (Prod.swap K J ⋙ F) ⋙ lim).obj k
⊢ limit.π (curry.obj F ⋙ colim) j (colimitLimitToLimitColimit F (colimit.ι (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) k f)) =
    colimit.ι ((curry.obj F).obj j) k (limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j f)

Next tactic:
dsimp [colimitLimitToLimitColimit]
@[simp]
theorem ι_colimitLimitToLimitColimit_π_apply (F : J × K ⥤ Type v) (j : J) (k : K) (f) :
    limit.π (curry.obj F ⋙ colim) j
        (colimitLimitToLimitColimit F (colimit.ι (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) k f)) =
      colimit.ι ((curry.obj F).obj j) k (limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j f) := by
  dsimp [colimitLimitToLimitColimit]
  

Proof state:
J K : Type v
inst✝⁴ : SmallCategory J
inst✝³ : SmallCategory K
C : Type u
inst✝² : Category.{v, u} C
F✝ : J × K ⥤ C
inst✝¹ : HasLimitsOfShape J C
inst✝ : HasColimitsOfShape K C
F : J × K ⥤ Type v
j : J
k : K
f : (curry.obj (Prod.swap K J ⋙ F) ⋙ lim).obj k
⊢ limit.π (curry.obj F ⋙ colim) j
      (limit.lift (curry.obj F ⋙ colim)
        { pt := colimit (curry.obj (Prod.swap K J ⋙ F) ⋙ lim),
          π :=
            NatTrans.mk fun j =>
              colimit.desc (curry.obj (Prod.swap K J ⋙ F) ⋙ lim)
                { pt := colimit ((curry.obj F).obj j),
                  ι :=
                    NatTrans.mk fun k =>
                      limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j ≫ colimit.ι ((curry.obj F).obj j) k } }
        (colimit.ι (curry.obj (Prod.swap K J ⋙ F) ⋙ lim) k f)) =
    colimit.ι ((curry.obj F).obj j) k (limit.π ((curry.obj (Prod.swap K J ⋙ F)).obj k) j f)

Next tactic:
simp
/-- The map `colimit_limit_to_limit_colimit` realized as a map of cones. -/
@[simps]
noncomputable def colimitLimitToLimitColimitCone (G : J ⥤ K ⥤ C) [HasLimit G] :
    colim.mapCone (limit.cone G) ⟶ limit.cone (G ⋙ colim)
    where
  hom :=
    colim.map (limitIsoSwapCompLim G).hom ≫
      colimitLimitToLimitColimit (uncurry.obj G : _) ≫
        lim.map (whiskerRight (currying.unitIso.app G).inv colim)
  w j := by
    

Proof state:
J K : Type v
inst✝⁵ : SmallCategory J
inst✝⁴ : SmallCategory K
C : Type u
inst✝³ : Category.{v, u} C
F : J × K ⥤ C
inst✝² : HasLimitsOfShape J C
inst✝¹ : HasColimitsOfShape K C
G : J ⥤ K ⥤ C
inst✝ : HasLimit G
j : J
⊢ (colim.map (limitIsoSwapCompLim G).hom ≫
        colimitLimitToLimitColimit (uncurry.obj G) ≫ lim.map (whiskerRight (currying.unitIso.app G).inv colim)) ≫
      (limit.cone (G ⋙ colim)).π.app j =
    (colim.mapCone (limit.cone G)).π.app j

Next tactic:
dsimp
/-- The map `colimit_limit_to_limit_colimit` realized as a map of cones. -/
@[simps]
noncomputable def colimitLimitToLimitColimitCone (G : J ⥤ K ⥤ C) [HasLimit G] :
    colim.mapCone (limit.cone G) ⟶ limit.cone (G ⋙ colim)
    where
  hom :=
    colim.map (limitIsoSwapCompLim G).hom ≫
      colimitLimitToLimitColimit (uncurry.obj G : _) ≫
        lim.map (whiskerRight (currying.unitIso.app G).inv colim)
  w j := by
    dsimp
    

Proof state:
J K : Type v
inst✝⁵ : SmallCategory J
inst✝⁴ : SmallCategory K
C : Type u
inst✝³ : Category.{v, u} C
F : J × K ⥤ C
inst✝² : HasLimitsOfShape J C
inst✝¹ : HasColimitsOfShape K C
G : J ⥤ K ⥤ C
inst✝ : HasLimit G
j : J
⊢ (colimMap (limitIsoSwapCompLim G).hom ≫
        colimitLimitToLimitColimit (uncurry.obj G) ≫ limMap (whiskerRight (currying.unitIso.inv.app G) colim)) ≫
      limit.π (G ⋙ colim) j =
    colimMap (limit.π G j)

Next tactic:
ext1 k
/-- The map `colimit_limit_to_limit_colimit` realized as a map of cones. -/
@[simps]
noncomputable def colimitLimitToLimitColimitCone (G : J ⥤ K ⥤ C) [HasLimit G] :
    colim.mapCone (limit.cone G) ⟶ limit.cone (G ⋙ colim)
    where
  hom :=
    colim.map (limitIsoSwapCompLim G).hom ≫
      colimitLimitToLimitColimit (uncurry.obj G : _) ≫
        lim.map (whiskerRight (currying.unitIso.app G).inv colim)
  w j := by
    dsimp
    ext1 k
    

Proof state:
case w
J K : Type v
inst✝⁵ : SmallCategory J
inst✝⁴ : SmallCategory K
C : Type u
inst✝³ : Category.{v, u} C
F : J × K ⥤ C
inst✝² : HasLimitsOfShape J C
inst✝¹ : HasColimitsOfShape K C
G : J ⥤ K ⥤ C
inst✝ : HasLimit G
j : J
k : K
⊢ colimit.ι (limit G) k ≫
      (colimMap (limitIsoSwapCompLim G).hom ≫
          colimitLimitToLimitColimit (uncurry.obj G) ≫ limMap (whiskerRight (currying.unitIso.inv.app G) colim)) ≫
        limit.π (G ⋙ colim) j =
    colimit.ι (limit G) k ≫ colimMap (limit.π G j)

Next tactic:
simp only [Category.assoc, limMap_π, Functor.comp_obj, colim_obj, whiskerRight_app,
      colim_map, ι_colimMap_assoc, lim_obj, limitIsoSwapCompLim_hom_app,
      ι_colimitLimitToLimitColimit_π_assoc, curry_obj_obj_obj, Prod.swap_obj,
      uncurry_obj_obj, ι_colimMap, currying_unitIso_inv_app_app_app, Category.id_comp,
      limMap_π_assoc, Functor.flip_obj_obj, flipIsoCurrySwapUncurry_hom_app_app]
/-- The map `colimit_limit_to_limit_colimit` realized as a map of cones. -/
@[simps]
noncomputable def colimitLimitToLimitColimitCone (G : J ⥤ K ⥤ C) [HasLimit G] :
    colim.mapCone (limit.cone G) ⟶ limit.cone (G ⋙ colim)
    where
  hom :=
    colim.map (limitIsoSwapCompLim G).hom ≫
      colimitLimitToLimitColimit (uncurry.obj G : _) ≫
        lim.map (whiskerRight (currying.unitIso.app G).inv colim)
  w j := by
    dsimp
    ext1 k
    simp only [Category.assoc, limMap_π, Functor.comp_obj, colim_obj, whiskerRight_app,
      colim_map, ι_colimMap_assoc, lim_obj, limitIsoSwapCompLim_hom_app,
      ι_colimitLimitToLimitColimit_π_assoc, curry_obj_obj_obj, Prod.swap_obj,
      uncurry_obj_obj, ι_colimMap, currying_unitIso_inv_app_app_app, Category.id_comp,
      limMap_π_assoc, Functor.flip_obj_obj, flipIsoCurrySwapUncurry_hom_app_app]
    

Proof state:
case w
J K : Type v
inst✝⁵ : SmallCategory J
inst✝⁴ : SmallCategory K
C : Type u
inst✝³ : Category.{v, u} C
F : J × K ⥤ C
inst✝² : HasLimitsOfShape J C
inst✝¹ : HasColimitsOfShape K C
G : J ⥤ K ⥤ C
inst✝ : HasLimit G
j : J
k : K
⊢ (limitObjIsoLimitCompEvaluation G k).hom ≫ limit.π ((Functor.flip G).obj k) j ≫ colimit.ι (G.obj j) k =
    (limit.π G j).app k ≫ colimit.ι (G.obj j) k

Next tactic:
erw [limitObjIsoLimitCompEvaluation_hom_π_assoc]
theorem Finite.exists_max [Finite α] [Nonempty α] [LinearOrder β] (f : α → β) :
    ∃ x₀ : α, ∀ x, f x ≤ f x₀ := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : Finite α
inst✝¹ : Nonempty α
inst✝ : LinearOrder β
f : α → β
⊢ ∃ x₀, ∀ (x : α), f x ≤ f x₀

Next tactic:
cases nonempty_fintype α
theorem Finite.exists_max [Finite α] [Nonempty α] [LinearOrder β] (f : α → β) :
    ∃ x₀ : α, ∀ x, f x ≤ f x₀ := by
  cases nonempty_fintype α
  

Proof state:
case intro
α : Type u_1
β : Type u_2
inst✝² : Finite α
inst✝¹ : Nonempty α
inst✝ : LinearOrder β
f : α → β
val✝ : Fintype α
⊢ ∃ x₀, ∀ (x : α), f x ≤ f x₀

Next tactic:
simpa using exists_max_image univ f univ_nonempty
theorem Finite.exists_min [Finite α] [Nonempty α] [LinearOrder β] (f : α → β) :
    ∃ x₀ : α, ∀ x, f x₀ ≤ f x := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : Finite α
inst✝¹ : Nonempty α
inst✝ : LinearOrder β
f : α → β
⊢ ∃ x₀, ∀ (x : α), f x₀ ≤ f x

Next tactic:
cases nonempty_fintype α
theorem Finite.exists_min [Finite α] [Nonempty α] [LinearOrder β] (f : α → β) :
    ∃ x₀ : α, ∀ x, f x₀ ≤ f x := by
  cases nonempty_fintype α
  

Proof state:
case intro
α : Type u_1
β : Type u_2
inst✝² : Finite α
inst✝¹ : Nonempty α
inst✝ : LinearOrder β
f : α → β
val✝ : Fintype α
⊢ ∃ x₀, ∀ (x : α), f x₀ ≤ f x

Next tactic:
simpa using exists_min_image univ f univ_nonempty
theorem zero_pow : ∀ {n : ℕ}, 0 < n → (0 : M) ^ n = 0
  | n + 1, _ => by 

Proof state:
R : Type u_1
S : Type u_2
M : Type u_3
inst✝ : MonoidWithZero M
n : ℕ
x✝ : 0 < n + 1
⊢ 0 ^ (n + 1) = 0

Next tactic:
rw [pow_succ, zero_mul]
@[simp]
theorem zero_pow' : ∀ n : ℕ, n ≠ 0 → (0 : M) ^ n = 0
  | 0, h => absurd rfl h
  | k + 1, _ => by
    

Proof state:
R : Type u_1
S : Type u_2
M : Type u_3
inst✝ : MonoidWithZero M
k : ℕ
x✝ : k + 1 ≠ 0
⊢ 0 ^ (k + 1) = 0

Next tactic:
rw [pow_succ]
@[simp]
theorem zero_pow' : ∀ n : ℕ, n ≠ 0 → (0 : M) ^ n = 0
  | 0, h => absurd rfl h
  | k + 1, _ => by
    rw [pow_succ]
    

Proof state:
R : Type u_1
S : Type u_2
M : Type u_3
inst✝ : MonoidWithZero M
k : ℕ
x✝ : k + 1 ≠ 0
⊢ 0 * 0 ^ k = 0

Next tactic:
exact zero_mul _
theorem zero_pow_eq (n : ℕ) : (0 : M) ^ n = if n = 0 then 1 else 0 := by
  

Proof state:
R : Type u_1
S : Type u_2
M : Type u_3
inst✝ : MonoidWithZero M
n : ℕ
⊢ 0 ^ n = if n = 0 then 1 else 0

Next tactic:
split_ifs with h
theorem zero_pow_eq (n : ℕ) : (0 : M) ^ n = if n = 0 then 1 else 0 := by
  split_ifs with h
  · 

Proof state:
case pos
R : Type u_1
S : Type u_2
M : Type u_3
inst✝ : MonoidWithZero M
n : ℕ
h : n = 0
⊢ 0 ^ n = 1

Next tactic:
rw [h, pow_zero]
theorem zero_pow_eq (n : ℕ) : (0 : M) ^ n = if n = 0 then 1 else 0 := by
  split_ifs with h
  · rw [h, pow_zero]
  · 

Proof state:
case neg
R : Type u_1
S : Type u_2
M : Type u_3
inst✝ : MonoidWithZero M
n : ℕ
h : ¬n = 0
⊢ 0 ^ n = 0

Next tactic:
rw [zero_pow (Nat.pos_of_ne_zero h)]
theorem pow_eq_zero_of_le {x : M} {n m : ℕ} (hn : n ≤ m) (hx : x ^ n = 0) : x ^ m = 0 := by
  

Proof state:
R : Type u_1
S : Type u_2
M : Type u_3
inst✝ : MonoidWithZero M
x : M
n m : ℕ
hn : n ≤ m
hx : x ^ n = 0
⊢ x ^ m = 0

Next tactic:
rw [← tsub_add_cancel_of_le hn, pow_add, hx, mul_zero]
theorem pow_eq_zero [NoZeroDivisors M] {x : M} {n : ℕ} (H : x ^ n = 0) : x = 0 := by
  

Proof state:
R : Type u_1
S : Type u_2
M : Type u_3
inst✝¹ : MonoidWithZero M
inst✝ : NoZeroDivisors M
x : M
n : ℕ
H : x ^ n = 0
⊢ x = 0

Next tactic:
induction' n with n ih
theorem pow_eq_zero [NoZeroDivisors M] {x : M} {n : ℕ} (H : x ^ n = 0) : x = 0 := by
  induction' n with n ih
  · 

Proof state:
case zero
R : Type u_1
S : Type u_2
M : Type u_3
inst✝¹ : MonoidWithZero M
inst✝ : NoZeroDivisors M
x : M
H : x ^ Nat.zero = 0
⊢ x = 0

Next tactic:
rw [pow_zero] at H
theorem pow_eq_zero [NoZeroDivisors M] {x : M} {n : ℕ} (H : x ^ n = 0) : x = 0 := by
  induction' n with n ih
  · rw [pow_zero] at H
    

Proof state:
case zero
R : Type u_1
S : Type u_2
M : Type u_3
inst✝¹ : MonoidWithZero M
inst✝ : NoZeroDivisors M
x : M
H : 1 = 0
⊢ x = 0

Next tactic:
rw [← mul_one x, H, mul_zero]
theorem pow_eq_zero [NoZeroDivisors M] {x : M} {n : ℕ} (H : x ^ n = 0) : x = 0 := by
  induction' n with n ih
  · rw [pow_zero] at H
    rw [← mul_one x, H, mul_zero]
  · 

Proof state:
case succ
R : Type u_1
S : Type u_2
M : Type u_3
inst✝¹ : MonoidWithZero M
inst✝ : NoZeroDivisors M
x : M
n : ℕ
ih : x ^ n = 0 → x = 0
H : x ^ Nat.succ n = 0
⊢ x = 0

Next tactic:
rw [pow_succ] at H
theorem pow_eq_zero [NoZeroDivisors M] {x : M} {n : ℕ} (H : x ^ n = 0) : x = 0 := by
  induction' n with n ih
  · rw [pow_zero] at H
    rw [← mul_one x, H, mul_zero]
  · rw [pow_succ] at H
    

Proof state:
case succ
R : Type u_1
S : Type u_2
M : Type u_3
inst✝¹ : MonoidWithZero M
inst✝ : NoZeroDivisors M
x : M
n : ℕ
ih : x ^ n = 0 → x = 0
H : x * x ^ n = 0
⊢ x = 0

Next tactic:
exact Or.casesOn (mul_eq_zero.1 H) id ih
@[simp]
theorem pow_eq_zero_iff [NoZeroDivisors M] {a : M} {n : ℕ} (hn : 0 < n) : a ^ n = 0 ↔ a = 0 := by
  

Proof state:
R : Type u_1
S : Type u_2
M : Type u_3
inst✝¹ : MonoidWithZero M
inst✝ : NoZeroDivisors M
a : M
n : ℕ
hn : 0 < n
⊢ a ^ n = 0 ↔ a = 0

Next tactic:
refine' ⟨pow_eq_zero, _⟩
@[simp]
theorem pow_eq_zero_iff [NoZeroDivisors M] {a : M} {n : ℕ} (hn : 0 < n) : a ^ n = 0 ↔ a = 0 := by
  refine' ⟨pow_eq_zero, _⟩
  

Proof state:
R : Type u_1
S : Type u_2
M : Type u_3
inst✝¹ : MonoidWithZero M
inst✝ : NoZeroDivisors M
a : M
n : ℕ
hn : 0 < n
⊢ a = 0 → a ^ n = 0

Next tactic:
rintro rfl