l3lab/ntp-mathlib huggingface dataset:
/-- If `X × -` preserves colimits in `D` for any `X : D`, then the product functor `F ⨯ -` for
`F : C ⥤ D` also preserves colimits.

Note this is (mathematically) a special case of the statement that
"if limits commute with colimits in `D`, then they do as well in `C ⥤ D`"
but the story in Lean is a bit more complex, and this statement isn't directly a special case.
That is, even with a formalised proof of the general statement, there would still need to be some
work to convert to this version: namely, the natural isomorphism
`(evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅
  prod.functor.obj F ⋙ (evaluation C D).obj k`
-/
def FunctorCategory.prodPreservesColimits [HasBinaryProducts D] [HasColimits D]
    [∀ X : D, PreservesColimits (prod.functor.obj X)] (F : C ⥤ D) :
    PreservesColimits (prod.functor.obj F) where
  preservesColimitsOfShape {J : Type u} [Category.{u, u} J] :=
    {
      preservesColimit := fun {K : J ⥤ C ⥤ D} =>
        ( {
          preserves := fun {c : Cocone K} (t : IsColimit c) => by
            apply evaluationJointlyReflectsColimits _ fun {k} => ?_
            

Proof state:
C : Type u
inst✝⁶ : Category.{v₁, u} C
D : Type u₂
inst✝⁵ : Category.{u, u₂} D
E : Type u
inst✝⁴ : Category.{v₂, u} E
inst✝³ : HasBinaryProducts D
inst✝² : HasColimits D
inst✝¹ : (X : D) → PreservesColimits (prod.functor.obj X)
F : C ⥤ D
J : Type u
inst✝ : Category.{u, u} J
K : J ⥤ C ⥤ D
c : Cocone K
t : IsColimit c
k : C
⊢ IsColimit (((evaluation C D).obj k).mapCocone ((prod.functor.obj F).mapCocone c))

Next tactic:
change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c)
/-- If `X × -` preserves colimits in `D` for any `X : D`, then the product functor `F ⨯ -` for
`F : C ⥤ D` also preserves colimits.

Note this is (mathematically) a special case of the statement that
"if limits commute with colimits in `D`, then they do as well in `C ⥤ D`"
but the story in Lean is a bit more complex, and this statement isn't directly a special case.
That is, even with a formalised proof of the general statement, there would still need to be some
work to convert to this version: namely, the natural isomorphism
`(evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅
  prod.functor.obj F ⋙ (evaluation C D).obj k`
-/
def FunctorCategory.prodPreservesColimits [HasBinaryProducts D] [HasColimits D]
    [∀ X : D, PreservesColimits (prod.functor.obj X)] (F : C ⥤ D) :
    PreservesColimits (prod.functor.obj F) where
  preservesColimitsOfShape {J : Type u} [Category.{u, u} J] :=
    {
      preservesColimit := fun {K : J ⥤ C ⥤ D} =>
        ( {
          preserves := fun {c : Cocone K} (t : IsColimit c) => by
            apply evaluationJointlyReflectsColimits _ fun {k} => ?_
            change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c)
            

Proof state:
C : Type u
inst✝⁶ : Category.{v₁, u} C
D : Type u₂
inst✝⁵ : Category.{u, u₂} D
E : Type u
inst✝⁴ : Category.{v₂, u} E
inst✝³ : HasBinaryProducts D
inst✝² : HasColimits D
inst✝¹ : (X : D) → PreservesColimits (prod.functor.obj X)
F : C ⥤ D
J : Type u
inst✝ : Category.{u, u} J
K : J ⥤ C ⥤ D
c : Cocone K
t : IsColimit c
k : C
⊢ IsColimit ((prod.functor.obj F ⋙ (evaluation C D).obj k).mapCocone c)

Next tactic:
let this :=
              isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
/-- If `X × -` preserves colimits in `D` for any `X : D`, then the product functor `F ⨯ -` for
`F : C ⥤ D` also preserves colimits.

Note this is (mathematically) a special case of the statement that
"if limits commute with colimits in `D`, then they do as well in `C ⥤ D`"
but the story in Lean is a bit more complex, and this statement isn't directly a special case.
That is, even with a formalised proof of the general statement, there would still need to be some
work to convert to this version: namely, the natural isomorphism
`(evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅
  prod.functor.obj F ⋙ (evaluation C D).obj k`
-/
def FunctorCategory.prodPreservesColimits [HasBinaryProducts D] [HasColimits D]
    [∀ X : D, PreservesColimits (prod.functor.obj X)] (F : C ⥤ D) :
    PreservesColimits (prod.functor.obj F) where
  preservesColimitsOfShape {J : Type u} [Category.{u, u} J] :=
    {
      preservesColimit := fun {K : J ⥤ C ⥤ D} =>
        ( {
          preserves := fun {c : Cocone K} (t : IsColimit c) => by
            apply evaluationJointlyReflectsColimits _ fun {k} => ?_
            change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c)
            let this :=
              isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
            

Proof state:
C : Type u
inst✝⁶ : Category.{v₁, u} C
D : Type u₂
inst✝⁵ : Category.{u, u₂} D
E : Type u
inst✝⁴ : Category.{v₂, u} E
inst✝³ : HasBinaryProducts D
inst✝² : HasColimits D
inst✝¹ : (X : D) → PreservesColimits (prod.functor.obj X)
F : C ⥤ D
J : Type u
inst✝ : Category.{u, u} J
K : J ⥤ C ⥤ D
c : Cocone K
t : IsColimit c
k : C
this : IsColimit (((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).mapCocone c) :=
  isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
⊢ IsColimit ((prod.functor.obj F ⋙ (evaluation C D).obj k).mapCocone c)

Next tactic:
apply IsColimit.mapCoconeEquiv _ this
/-- If `X × -` preserves colimits in `D` for any `X : D`, then the product functor `F ⨯ -` for
`F : C ⥤ D` also preserves colimits.

Note this is (mathematically) a special case of the statement that
"if limits commute with colimits in `D`, then they do as well in `C ⥤ D`"
but the story in Lean is a bit more complex, and this statement isn't directly a special case.
That is, even with a formalised proof of the general statement, there would still need to be some
work to convert to this version: namely, the natural isomorphism
`(evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅
  prod.functor.obj F ⋙ (evaluation C D).obj k`
-/
def FunctorCategory.prodPreservesColimits [HasBinaryProducts D] [HasColimits D]
    [∀ X : D, PreservesColimits (prod.functor.obj X)] (F : C ⥤ D) :
    PreservesColimits (prod.functor.obj F) where
  preservesColimitsOfShape {J : Type u} [Category.{u, u} J] :=
    {
      preservesColimit := fun {K : J ⥤ C ⥤ D} =>
        ( {
          preserves := fun {c : Cocone K} (t : IsColimit c) => by
            apply evaluationJointlyReflectsColimits _ fun {k} => ?_
            change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c)
            let this :=
              isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
            apply IsColimit.mapCoconeEquiv _ this
            

Proof state:
C : Type u
inst✝⁶ : Category.{v₁, u} C
D : Type u₂
inst✝⁵ : Category.{u, u₂} D
E : Type u
inst✝⁴ : Category.{v₂, u} E
inst✝³ : HasBinaryProducts D
inst✝² : HasColimits D
inst✝¹ : (X : D) → PreservesColimits (prod.functor.obj X)
F : C ⥤ D
J : Type u
inst✝ : Category.{u, u} J
K : J ⥤ C ⥤ D
c : Cocone K
t : IsColimit c
k : C
this : IsColimit (((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).mapCocone c) :=
  isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
⊢ (evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅ prod.functor.obj F ⋙ (evaluation C D).obj k

Next tactic:
apply (NatIso.ofComponents _ _).symm
/-- If `X × -` preserves colimits in `D` for any `X : D`, then the product functor `F ⨯ -` for
`F : C ⥤ D` also preserves colimits.

Note this is (mathematically) a special case of the statement that
"if limits commute with colimits in `D`, then they do as well in `C ⥤ D`"
but the story in Lean is a bit more complex, and this statement isn't directly a special case.
That is, even with a formalised proof of the general statement, there would still need to be some
work to convert to this version: namely, the natural isomorphism
`(evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅
  prod.functor.obj F ⋙ (evaluation C D).obj k`
-/
def FunctorCategory.prodPreservesColimits [HasBinaryProducts D] [HasColimits D]
    [∀ X : D, PreservesColimits (prod.functor.obj X)] (F : C ⥤ D) :
    PreservesColimits (prod.functor.obj F) where
  preservesColimitsOfShape {J : Type u} [Category.{u, u} J] :=
    {
      preservesColimit := fun {K : J ⥤ C ⥤ D} =>
        ( {
          preserves := fun {c : Cocone K} (t : IsColimit c) => by
            apply evaluationJointlyReflectsColimits _ fun {k} => ?_
            change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c)
            let this :=
              isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
            apply IsColimit.mapCoconeEquiv _ this
            apply (NatIso.ofComponents _ _).symm
            · 

Proof state:
C : Type u
inst✝⁶ : Category.{v₁, u} C
D : Type u₂
inst✝⁵ : Category.{u, u₂} D
E : Type u
inst✝⁴ : Category.{v₂, u} E
inst✝³ : HasBinaryProducts D
inst✝² : HasColimits D
inst✝¹ : (X : D) → PreservesColimits (prod.functor.obj X)
F : C ⥤ D
J : Type u
inst✝ : Category.{u, u} J
K : J ⥤ C ⥤ D
c : Cocone K
t : IsColimit c
k : C
this : IsColimit (((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).mapCocone c) :=
  isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
⊢ (X : C ⥤ D) →
    (prod.functor.obj F ⋙ (evaluation C D).obj k).obj X ≅ ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).obj X

Next tactic:
intro G
/-- If `X × -` preserves colimits in `D` for any `X : D`, then the product functor `F ⨯ -` for
`F : C ⥤ D` also preserves colimits.

Note this is (mathematically) a special case of the statement that
"if limits commute with colimits in `D`, then they do as well in `C ⥤ D`"
but the story in Lean is a bit more complex, and this statement isn't directly a special case.
That is, even with a formalised proof of the general statement, there would still need to be some
work to convert to this version: namely, the natural isomorphism
`(evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅
  prod.functor.obj F ⋙ (evaluation C D).obj k`
-/
def FunctorCategory.prodPreservesColimits [HasBinaryProducts D] [HasColimits D]
    [∀ X : D, PreservesColimits (prod.functor.obj X)] (F : C ⥤ D) :
    PreservesColimits (prod.functor.obj F) where
  preservesColimitsOfShape {J : Type u} [Category.{u, u} J] :=
    {
      preservesColimit := fun {K : J ⥤ C ⥤ D} =>
        ( {
          preserves := fun {c : Cocone K} (t : IsColimit c) => by
            apply evaluationJointlyReflectsColimits _ fun {k} => ?_
            change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c)
            let this :=
              isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
            apply IsColimit.mapCoconeEquiv _ this
            apply (NatIso.ofComponents _ _).symm
            · intro G
              

Proof state:
C : Type u
inst✝⁶ : Category.{v₁, u} C
D : Type u₂
inst✝⁵ : Category.{u, u₂} D
E : Type u
inst✝⁴ : Category.{v₂, u} E
inst✝³ : HasBinaryProducts D
inst✝² : HasColimits D
inst✝¹ : (X : D) → PreservesColimits (prod.functor.obj X)
F : C ⥤ D
J : Type u
inst✝ : Category.{u, u} J
K : J ⥤ C ⥤ D
c : Cocone K
t : IsColimit c
k : C
this : IsColimit (((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).mapCocone c) :=
  isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
G : C ⥤ D
⊢ (prod.functor.obj F ⋙ (evaluation C D).obj k).obj G ≅ ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).obj G

Next tactic:
apply asIso (prodComparison ((evaluation C D).obj k) F G)
/-- If `X × -` preserves colimits in `D` for any `X : D`, then the product functor `F ⨯ -` for
`F : C ⥤ D` also preserves colimits.

Note this is (mathematically) a special case of the statement that
"if limits commute with colimits in `D`, then they do as well in `C ⥤ D`"
but the story in Lean is a bit more complex, and this statement isn't directly a special case.
That is, even with a formalised proof of the general statement, there would still need to be some
work to convert to this version: namely, the natural isomorphism
`(evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅
  prod.functor.obj F ⋙ (evaluation C D).obj k`
-/
def FunctorCategory.prodPreservesColimits [HasBinaryProducts D] [HasColimits D]
    [∀ X : D, PreservesColimits (prod.functor.obj X)] (F : C ⥤ D) :
    PreservesColimits (prod.functor.obj F) where
  preservesColimitsOfShape {J : Type u} [Category.{u, u} J] :=
    {
      preservesColimit := fun {K : J ⥤ C ⥤ D} =>
        ( {
          preserves := fun {c : Cocone K} (t : IsColimit c) => by
            apply evaluationJointlyReflectsColimits _ fun {k} => ?_
            change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c)
            let this :=
              isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
            apply IsColimit.mapCoconeEquiv _ this
            apply (NatIso.ofComponents _ _).symm
            · intro G
              apply asIso (prodComparison ((evaluation C D).obj k) F G)
            · 

Proof state:
C : Type u
inst✝⁶ : Category.{v₁, u} C
D : Type u₂
inst✝⁵ : Category.{u, u₂} D
E : Type u
inst✝⁴ : Category.{v₂, u} E
inst✝³ : HasBinaryProducts D
inst✝² : HasColimits D
inst✝¹ : (X : D) → PreservesColimits (prod.functor.obj X)
F : C ⥤ D
J : Type u
inst✝ : Category.{u, u} J
K : J ⥤ C ⥤ D
c : Cocone K
t : IsColimit c
k : C
this : IsColimit (((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).mapCocone c) :=
  isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
⊢ ∀ {X Y : C ⥤ D} (f : X ⟶ Y),
    (prod.functor.obj F ⋙ (evaluation C D).obj k).map f ≫ (asIso (prodComparison ((evaluation C D).obj k) F Y)).hom =
      (asIso (prodComparison ((evaluation C D).obj k) F X)).hom ≫
        ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).map f

Next tactic:
intro G G'
/-- If `X × -` preserves colimits in `D` for any `X : D`, then the product functor `F ⨯ -` for
`F : C ⥤ D` also preserves colimits.

Note this is (mathematically) a special case of the statement that
"if limits commute with colimits in `D`, then they do as well in `C ⥤ D`"
but the story in Lean is a bit more complex, and this statement isn't directly a special case.
That is, even with a formalised proof of the general statement, there would still need to be some
work to convert to this version: namely, the natural isomorphism
`(evaluation C D).obj k ⋙ prod.functor.obj (F.obj k) ≅
  prod.functor.obj F ⋙ (evaluation C D).obj k`
-/
def FunctorCategory.prodPreservesColimits [HasBinaryProducts D] [HasColimits D]
    [∀ X : D, PreservesColimits (prod.functor.obj X)] (F : C ⥤ D) :
    PreservesColimits (prod.functor.obj F) where
  preservesColimitsOfShape {J : Type u} [Category.{u, u} J] :=
    {
      preservesColimit := fun {K : J ⥤ C ⥤ D} =>
        ( {
          preserves := fun {c : Cocone K} (t : IsColimit c) => by
            apply evaluationJointlyReflectsColimits _ fun {k} => ?_
            change IsColimit ((prod.functor.obj F ⋙ (evaluation _ _).obj k).mapCocone c)
            let this :=
              isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
            apply IsColimit.mapCoconeEquiv _ this
            apply (NatIso.ofComponents _ _).symm
            · intro G
              apply asIso (prodComparison ((evaluation C D).obj k) F G)
            · intro G G'
              

Proof state:
C : Type u
inst✝⁶ : Category.{v₁, u} C
D : Type u₂
inst✝⁵ : Category.{u, u₂} D
E : Type u
inst✝⁴ : Category.{v₂, u} E
inst✝³ : HasBinaryProducts D
inst✝² : HasColimits D
inst✝¹ : (X : D) → PreservesColimits (prod.functor.obj X)
F : C ⥤ D
J : Type u
inst✝ : Category.{u, u} J
K : J ⥤ C ⥤ D
c : Cocone K
t : IsColimit c
k : C
this : IsColimit (((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).mapCocone c) :=
  isColimitOfPreserves ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)) t
G G' : C ⥤ D
⊢ ∀ (f : G ⟶ G'),
    (prod.functor.obj F ⋙ (evaluation C D).obj k).map f ≫ (asIso (prodComparison ((evaluation C D).obj k) F G')).hom =
      (asIso (prodComparison ((evaluation C D).obj k) F G)).hom ≫
        ((evaluation C D).obj k ⋙ prod.functor.obj (F.obj k)).map f

Next tactic:
apply prodComparison_natural ((evaluation C D).obj k) (𝟙 F)
instance whiskeringLeftPreservesLimits [HasLimits D] (F : C ⥤ E) :
    PreservesLimits ((whiskeringLeft C E D).obj F) :=
  ⟨fun {J} [hJ : Category J] =>
    ⟨fun {K} =>
      ⟨fun c {hc} => by
        

Proof state:
C : Type u
inst✝³ : Category.{v₁, u} C
D : Type u₂
inst✝² : Category.{u, u₂} D
E : Type u
inst✝¹ : Category.{v₂, u} E
inst✝ : HasLimits D
F : C ⥤ E
J : Type u
hJ : Category.{u, u} J
K : J ⥤ E ⥤ D
c : Cone K
hc : IsLimit c
⊢ IsLimit (((whiskeringLeft C E D).obj F).mapCone c)

Next tactic:
apply evaluationJointlyReflectsLimits
instance whiskeringLeftPreservesLimits [HasLimits D] (F : C ⥤ E) :
    PreservesLimits ((whiskeringLeft C E D).obj F) :=
  ⟨fun {J} [hJ : Category J] =>
    ⟨fun {K} =>
      ⟨fun c {hc} => by
        apply evaluationJointlyReflectsLimits
        

Proof state:
case t
C : Type u
inst✝³ : Category.{v₁, u} C
D : Type u₂
inst✝² : Category.{u, u₂} D
E : Type u
inst✝¹ : Category.{v₂, u} E
inst✝ : HasLimits D
F : C ⥤ E
J : Type u
hJ : Category.{u, u} J
K : J ⥤ E ⥤ D
c : Cone K
hc : IsLimit c
⊢ (k : C) → IsLimit (((evaluation C D).obj k).mapCone (((whiskeringLeft C E D).obj F).mapCone c))

Next tactic:
intro Y
instance whiskeringLeftPreservesLimits [HasLimits D] (F : C ⥤ E) :
    PreservesLimits ((whiskeringLeft C E D).obj F) :=
  ⟨fun {J} [hJ : Category J] =>
    ⟨fun {K} =>
      ⟨fun c {hc} => by
        apply evaluationJointlyReflectsLimits
        intro Y
        

Proof state:
case t
C : Type u
inst✝³ : Category.{v₁, u} C
D : Type u₂
inst✝² : Category.{u, u₂} D
E : Type u
inst✝¹ : Category.{v₂, u} E
inst✝ : HasLimits D
F : C ⥤ E
J : Type u
hJ : Category.{u, u} J
K : J ⥤ E ⥤ D
c : Cone K
hc : IsLimit c
Y : C
⊢ IsLimit (((evaluation C D).obj Y).mapCone (((whiskeringLeft C E D).obj F).mapCone c))

Next tactic:
change IsLimit (((evaluation E D).obj (F.obj Y)).mapCone c)
instance whiskeringLeftPreservesLimits [HasLimits D] (F : C ⥤ E) :
    PreservesLimits ((whiskeringLeft C E D).obj F) :=
  ⟨fun {J} [hJ : Category J] =>
    ⟨fun {K} =>
      ⟨fun c {hc} => by
        apply evaluationJointlyReflectsLimits
        intro Y
        change IsLimit (((evaluation E D).obj (F.obj Y)).mapCone c)
        

Proof state:
case t
C : Type u
inst✝³ : Category.{v₁, u} C
D : Type u₂
inst✝² : Category.{u, u₂} D
E : Type u
inst✝¹ : Category.{v₂, u} E
inst✝ : HasLimits D
F : C ⥤ E
J : Type u
hJ : Category.{u, u} J
K : J ⥤ E ⥤ D
c : Cone K
hc : IsLimit c
Y : C
⊢ IsLimit (((evaluation E D).obj (F.obj Y)).mapCone c)

Next tactic:
exact PreservesLimit.preserves hc
instance whiskeringRightPreservesLimitsOfShape {C : Type u} [Category C] {D : Type*}
    [Category.{u} D] {E : Type*} [Category.{u} E] {J : Type u} [SmallCategory J]
    [HasLimitsOfShape J D] (F : D ⥤ E) [PreservesLimitsOfShape J F] :
    PreservesLimitsOfShape J ((whiskeringRight C D E).obj F) :=
  ⟨fun {K} =>
    ⟨fun c {hc} => by
      

Proof state:
C✝ : Type u
inst✝⁸ : Category.{v₁, u} C✝
D✝ : Type u₂
inst✝⁷ : Category.{u, u₂} D✝
E✝ : Type u
inst✝⁶ : Category.{v₂, u} E✝
C : Type u
inst✝⁵ : Category.{?u.26512, u} C
D : Type u_1
inst✝⁴ : Category.{u, u_1} D
E : Type u_2
inst✝³ : Category.{u, u_2} E
J : Type u
inst✝² : SmallCategory J
inst✝¹ : HasLimitsOfShape J D
F : D ⥤ E
inst✝ : PreservesLimitsOfShape J F
K : J ⥤ C ⥤ D
c : Cone K
hc : IsLimit c
⊢ IsLimit (((whiskeringRight C D E).obj F).mapCone c)

Next tactic:
apply evaluationJointlyReflectsLimits _ (fun k => ?_)
instance whiskeringRightPreservesLimitsOfShape {C : Type u} [Category C] {D : Type*}
    [Category.{u} D] {E : Type*} [Category.{u} E] {J : Type u} [SmallCategory J]
    [HasLimitsOfShape J D] (F : D ⥤ E) [PreservesLimitsOfShape J F] :
    PreservesLimitsOfShape J ((whiskeringRight C D E).obj F) :=
  ⟨fun {K} =>
    ⟨fun c {hc} => by
      apply evaluationJointlyReflectsLimits _ (fun k => ?_)
      

Proof state:
C✝ : Type u
inst✝⁸ : Category.{v₁, u} C✝
D✝ : Type u₂
inst✝⁷ : Category.{u, u₂} D✝
E✝ : Type u
inst✝⁶ : Category.{v₂, u} E✝
C : Type u
inst✝⁵ : Category.{?u.26512, u} C
D : Type u_1
inst✝⁴ : Category.{u, u_1} D
E : Type u_2
inst✝³ : Category.{u, u_2} E
J : Type u
inst✝² : SmallCategory J
inst✝¹ : HasLimitsOfShape J D
F : D ⥤ E
inst✝ : PreservesLimitsOfShape J F
K : J ⥤ C ⥤ D
c : Cone K
hc : IsLimit c
k : C
⊢ IsLimit (((evaluation C E).obj k).mapCone (((whiskeringRight C D E).obj F).mapCone c))

Next tactic:
change IsLimit (((evaluation _ _).obj k ⋙ F).mapCone c)
instance whiskeringRightPreservesLimitsOfShape {C : Type u} [Category C] {D : Type*}
    [Category.{u} D] {E : Type*} [Category.{u} E] {J : Type u} [SmallCategory J]
    [HasLimitsOfShape J D] (F : D ⥤ E) [PreservesLimitsOfShape J F] :
    PreservesLimitsOfShape J ((whiskeringRight C D E).obj F) :=
  ⟨fun {K} =>
    ⟨fun c {hc} => by
      apply evaluationJointlyReflectsLimits _ (fun k => ?_)
      change IsLimit (((evaluation _ _).obj k ⋙ F).mapCone c)
      

Proof state:
C✝ : Type u
inst✝⁸ : Category.{v₁, u} C✝
D✝ : Type u₂
inst✝⁷ : Category.{u, u₂} D✝
E✝ : Type u
inst✝⁶ : Category.{v₂, u} E✝
C : Type u
inst✝⁵ : Category.{?u.26512, u} C
D : Type u_1
inst✝⁴ : Category.{u, u_1} D
E : Type u_2
inst✝³ : Category.{u, u_2} E
J : Type u
inst✝² : SmallCategory J
inst✝¹ : HasLimitsOfShape J D
F : D ⥤ E
inst✝ : PreservesLimitsOfShape J F
K : J ⥤ C ⥤ D
c : Cone K
hc : IsLimit c
k : C
⊢ IsLimit (((evaluation C D).obj k ⋙ F).mapCone c)

Next tactic:
exact PreservesLimit.preserves hc
/-- If `Lan F.op : (Cᵒᵖ ⥤ Type*) ⥤ (Dᵒᵖ ⥤ Type*)` preserves limits of shape `J`, so will `F`. -/
noncomputable def preservesLimitOfLanPreservesLimit {C D : Type u} [SmallCategory C]
    [SmallCategory D] (F : C ⥤ D) (J : Type u) [SmallCategory J]
    [PreservesLimitsOfShape J (lan F.op : _ ⥤ Dᵒᵖ ⥤ Type u)] : PreservesLimitsOfShape J F := by
  

Proof state:
C✝ : Type u
inst✝⁶ : Category.{v₁, u} C✝
D✝ : Type u₂
inst✝⁵ : Category.{u, u₂} D✝
E : Type u
inst✝⁴ : Category.{v₂, u} E
C D : Type u
inst✝³ : SmallCategory C
inst✝² : SmallCategory D
F : C ⥤ D
J : Type u
inst✝¹ : SmallCategory J
inst✝ : PreservesLimitsOfShape J (lan F.op)
⊢ PreservesLimitsOfShape J F

Next tactic:
apply @preservesLimitsOfShapeOfReflectsOfPreserves _ _ _ _ _ _ _ _ F yoneda ?_
/-- If `Lan F.op : (Cᵒᵖ ⥤ Type*) ⥤ (Dᵒᵖ ⥤ Type*)` preserves limits of shape `J`, so will `F`. -/
noncomputable def preservesLimitOfLanPreservesLimit {C D : Type u} [SmallCategory C]
    [SmallCategory D] (F : C ⥤ D) (J : Type u) [SmallCategory J]
    [PreservesLimitsOfShape J (lan F.op : _ ⥤ Dᵒᵖ ⥤ Type u)] : PreservesLimitsOfShape J F := by
  apply @preservesLimitsOfShapeOfReflectsOfPreserves _ _ _ _ _ _ _ _ F yoneda ?_
  

Proof state:
C✝ : Type u
inst✝⁶ : Category.{v₁, u} C✝
D✝ : Type u₂
inst✝⁵ : Category.{u, u₂} D✝
E : Type u
inst✝⁴ : Category.{v₂, u} E
C D : Type u
inst✝³ : SmallCategory C
inst✝² : SmallCategory D
F : C ⥤ D
J : Type u
inst✝¹ : SmallCategory J
inst✝ : PreservesLimitsOfShape J (lan F.op)
⊢ PreservesLimitsOfShape J (F ⋙ yoneda)

Next tactic:
exact preservesLimitsOfShapeOfNatIso (compYonedaIsoYonedaCompLan F).symm
@[simp] lemma compProd_zero_left (κ : kernel α β) : (0 : Measure α) ⊗ₘ κ = 0 := by 

Proof state:
α : Type u_1
β : Type u_2
mα : MeasurableSpace α
mβ : MeasurableSpace β
μ : Measure α
κ✝ η κ : ↥(kernel α β)
⊢ 0 ⊗ₘ κ = 0

Next tactic:
simp [compProd]
@[simp] lemma compProd_zero_right (μ : Measure α) : μ ⊗ₘ (0 : kernel α β) = 0 := by 

Proof state:
α : Type u_1
β : Type u_2
mα : MeasurableSpace α
mβ : MeasurableSpace β
μ✝ : Measure α
κ η : ↥(kernel α β)
μ : Measure α
⊢ μ ⊗ₘ 0 = 0

Next tactic:
simp [compProd]
lemma compProd_apply [SFinite μ] [IsSFiniteKernel κ] {s : Set (α × β)} (hs : MeasurableSet s) :
    (μ ⊗ₘ κ) s = ∫⁻ a, κ a (Prod.mk a ⁻¹' s) ∂μ := by
  

Proof state:
α : Type u_1
β : Type u_2
mα : MeasurableSpace α
mβ : MeasurableSpace β
μ : Measure α
κ η : ↥(kernel α β)
inst✝¹ : SFinite μ
inst✝ : IsSFiniteKernel κ
s : Set (α × β)
hs : MeasurableSet s
⊢ ↑↑(μ ⊗ₘ κ) s = ∫⁻ (a : α), ↑↑(κ a) (Prod.mk a ⁻¹' s) ∂μ

Next tactic:
simp_rw [compProd, kernel.compProd_apply _ _ _ hs, kernel.const_apply, kernel.prodMkLeft_apply']