l3lab/ntp-mathlib huggingface dataset:
/-- If `F` preserves the terminal object and binary products, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndTerminal :
    ∀ (n : ℕ) (f : Fin n → C), PreservesLimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesLimitsOfShape (Discrete (Fin 0)) F :=
      preservesLimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndTerminal n
    intro f
    refine'
      preservesLimitOfPreservesLimitCone
        (extendFanIsLimit f (limit.isLimit _) (limit.isLimit _)) _
    apply (isLimitMapConeFanMkEquiv _ _ _).symm _
    let this :=
      extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F _)
        (isLimitOfHasBinaryProductOfPreservesLimit F _ _)
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteProducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesLimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsLimit
  (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
    (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))) :=
  extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F fun i => f (Fin.succ i))
    (isLimitOfHasBinaryProductOfPreservesLimit F (f 0) (∏ fun i => f (Fin.succ i)))
⊢ IsLimit
    (Fan.mk (F.obj (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt) fun j =>
      F.map
        (Fin.cases (BinaryFan.fst (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)))
          (fun i =>
            BinaryFan.snd (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)) ≫
              (limit.cone (Discrete.functor fun i => f (Fin.succ i))).π.app { as := i })
          j))

Next tactic:
refine' IsLimit.ofIsoLimit this _
/-- If `F` preserves the terminal object and binary products, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndTerminal :
    ∀ (n : ℕ) (f : Fin n → C), PreservesLimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesLimitsOfShape (Discrete (Fin 0)) F :=
      preservesLimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndTerminal n
    intro f
    refine'
      preservesLimitOfPreservesLimitCone
        (extendFanIsLimit f (limit.isLimit _) (limit.isLimit _)) _
    apply (isLimitMapConeFanMkEquiv _ _ _).symm _
    let this :=
      extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F _)
        (isLimitOfHasBinaryProductOfPreservesLimit F _ _)
    refine' IsLimit.ofIsoLimit this _
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteProducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesLimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsLimit
  (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
    (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))) :=
  extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F fun i => f (Fin.succ i))
    (isLimitOfHasBinaryProductOfPreservesLimit F (f 0) (∏ fun i => f (Fin.succ i)))
⊢ extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
      (BinaryFan.mk (F.map prod.fst) (F.map prod.snd)) ≅
    Fan.mk (F.obj (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt) fun j =>
      F.map
        (Fin.cases (BinaryFan.fst (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)))
          (fun i =>
            BinaryFan.snd (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)) ≫
              (limit.cone (Discrete.functor fun i => f (Fin.succ i))).π.app { as := i })
          j)

Next tactic:
apply Cones.ext _ _
/-- If `F` preserves the terminal object and binary products, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndTerminal :
    ∀ (n : ℕ) (f : Fin n → C), PreservesLimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesLimitsOfShape (Discrete (Fin 0)) F :=
      preservesLimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndTerminal n
    intro f
    refine'
      preservesLimitOfPreservesLimitCone
        (extendFanIsLimit f (limit.isLimit _) (limit.isLimit _)) _
    apply (isLimitMapConeFanMkEquiv _ _ _).symm _
    let this :=
      extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F _)
        (isLimitOfHasBinaryProductOfPreservesLimit F _ _)
    refine' IsLimit.ofIsoLimit this _
    apply Cones.ext _ _
    apply Iso.refl _
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteProducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesLimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsLimit
  (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
    (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))) :=
  extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F fun i => f (Fin.succ i))
    (isLimitOfHasBinaryProductOfPreservesLimit F (f 0) (∏ fun i => f (Fin.succ i)))
⊢ ∀ (j : Discrete (Fin (n + 1))),
    (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
              (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))).π.app
        j =
      (Iso.refl
            (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
                (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))).pt).hom ≫
        (Fan.mk (F.obj (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt) fun j =>
                F.map
                  (Fin.cases
                    (BinaryFan.fst (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                    (fun i =>
                      BinaryFan.snd
                          (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)) ≫
                        (limit.cone (Discrete.functor fun i => f (Fin.succ i))).π.app { as := i })
                    j)).π.app
          j

Next tactic:
rintro ⟨j⟩
/-- If `F` preserves the terminal object and binary products, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndTerminal :
    ∀ (n : ℕ) (f : Fin n → C), PreservesLimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesLimitsOfShape (Discrete (Fin 0)) F :=
      preservesLimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndTerminal n
    intro f
    refine'
      preservesLimitOfPreservesLimitCone
        (extendFanIsLimit f (limit.isLimit _) (limit.isLimit _)) _
    apply (isLimitMapConeFanMkEquiv _ _ _).symm _
    let this :=
      extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F _)
        (isLimitOfHasBinaryProductOfPreservesLimit F _ _)
    refine' IsLimit.ofIsoLimit this _
    apply Cones.ext _ _
    apply Iso.refl _
    rintro ⟨j⟩
    

Proof state:
case mk
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteProducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesLimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsLimit
  (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
    (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))) :=
  extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F fun i => f (Fin.succ i))
    (isLimitOfHasBinaryProductOfPreservesLimit F (f 0) (∏ fun i => f (Fin.succ i)))
j : Fin (n + 1)
⊢ (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
            (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))).π.app
      { as := j } =
    (Iso.refl
          (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
              (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))).pt).hom ≫
      (Fan.mk (F.obj (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt) fun j =>
              F.map
                (Fin.cases
                  (BinaryFan.fst (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                  (fun i =>
                    BinaryFan.snd (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)) ≫
                      (limit.cone (Discrete.functor fun i => f (Fin.succ i))).π.app { as := i })
                  j)).π.app
        { as := j }

Next tactic:
refine' Fin.inductionOn j ?_ ?_
/-- If `F` preserves the terminal object and binary products, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndTerminal :
    ∀ (n : ℕ) (f : Fin n → C), PreservesLimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesLimitsOfShape (Discrete (Fin 0)) F :=
      preservesLimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndTerminal n
    intro f
    refine'
      preservesLimitOfPreservesLimitCone
        (extendFanIsLimit f (limit.isLimit _) (limit.isLimit _)) _
    apply (isLimitMapConeFanMkEquiv _ _ _).symm _
    let this :=
      extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F _)
        (isLimitOfHasBinaryProductOfPreservesLimit F _ _)
    refine' IsLimit.ofIsoLimit this _
    apply Cones.ext _ _
    apply Iso.refl _
    rintro ⟨j⟩
    refine' Fin.inductionOn j ?_ ?_
    · 

Proof state:
case mk.refine'_1
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteProducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesLimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsLimit
  (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
    (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))) :=
  extendFanIsLimit (fun i => F.obj (f i)) (isLimitOfHasProductOfPreservesLimit F fun i => f (Fin.succ i))
    (isLimitOfHasBinaryProductOfPreservesLimit F (f 0) (∏ fun i => f (Fin.succ i)))
j : Fin (n + 1)
⊢ (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
            (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))).π.app
      { as := 0 } =
    (Iso.refl
          (extendFan (Fan.mk (F.obj (∏ fun i => f (Fin.succ i))) fun j => F.map (Pi.π (fun i => f (Fin.succ i)) j))
              (BinaryFan.mk (F.map prod.fst) (F.map prod.snd))).pt).hom ≫
      (Fan.mk (F.obj (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt) fun j =>
              F.map
                (Fin.cases
                  (BinaryFan.fst (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                  (fun i =>
                    BinaryFan.snd (limit.cone (pair (f 0) (limit.cone (Discrete.functor fun i => f (Fin.succ i))).pt)) ≫
                      (limit.cone (Discrete.functor fun i => f (Fin.succ i))).π.app { as := i })
                  j)).π.app
        { as := 0 }

Next tactic:
apply (Category.id_comp _).symm
/-- If `F` preserves the terminal object and binary products, then it preserves limits of shape
`Discrete (Fin n)`.
-/
def preservesShapeFinOfPreservesBinaryAndTerminal (n : ℕ) :
    PreservesLimitsOfShape (Discrete (Fin n)) F where
  preservesLimit {K} := by
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteProducts C
n : ℕ
K : Discrete (Fin n) ⥤ C
⊢ PreservesLimit K F

Next tactic:
let that : (Discrete.functor fun n => K.obj ⟨n⟩) ≅ K := Discrete.natIso fun ⟨i⟩ => Iso.refl _
/-- If `F` preserves the terminal object and binary products, then it preserves limits of shape
`Discrete (Fin n)`.
-/
def preservesShapeFinOfPreservesBinaryAndTerminal (n : ℕ) :
    PreservesLimitsOfShape (Discrete (Fin n)) F where
  preservesLimit {K} := by
    let that : (Discrete.functor fun n => K.obj ⟨n⟩) ≅ K := Discrete.natIso fun ⟨i⟩ => Iso.refl _
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteProducts C
n : ℕ
K : Discrete (Fin n) ⥤ C
that : (Discrete.functor fun n_1 => K.obj { as := n_1 }) ≅ K :=
  Discrete.natIso fun x =>
    match x with
    | { as := i } => Iso.refl ((Discrete.functor fun n_1 => K.obj { as := n_1 }).obj { as := i })
⊢ PreservesLimit K F

Next tactic:
haveI := preservesFinOfPreservesBinaryAndTerminal F n fun n => K.obj ⟨n⟩
/-- If `F` preserves the terminal object and binary products, then it preserves limits of shape
`Discrete (Fin n)`.
-/
def preservesShapeFinOfPreservesBinaryAndTerminal (n : ℕ) :
    PreservesLimitsOfShape (Discrete (Fin n)) F where
  preservesLimit {K} := by
    let that : (Discrete.functor fun n => K.obj ⟨n⟩) ≅ K := Discrete.natIso fun ⟨i⟩ => Iso.refl _
    haveI := preservesFinOfPreservesBinaryAndTerminal F n fun n => K.obj ⟨n⟩
    

Proof state:
J : Type v
inst✝⁵ : SmallCategory J
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u'
inst✝³ : Category.{v', u'} D
F : C ⥤ D
inst✝² : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteProducts C
n : ℕ
K : Discrete (Fin n) ⥤ C
that : (Discrete.functor fun n_1 => K.obj { as := n_1 }) ≅ K :=
  Discrete.natIso fun x =>
    match x with
    | { as := i } => Iso.refl ((Discrete.functor fun n_1 => K.obj { as := n_1 }).obj { as := i })
this : PreservesLimit (Discrete.functor fun n_1 => K.obj { as := n_1 }) F
⊢ PreservesLimit K F

Next tactic:
apply preservesLimitOfIsoDiagram F that
/-- If `F` preserves the terminal object and binary products then it preserves finite products. -/
def preservesFiniteProductsOfPreservesBinaryAndTerminal (J : Type) [Fintype J] :
    PreservesLimitsOfShape (Discrete J) F := by
  

Proof state:
J✝ : Type v
inst✝⁶ : SmallCategory J✝
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
F : C ⥤ D
inst✝³ : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝² : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝¹ : HasFiniteProducts C
J : Type
inst✝ : Fintype J
⊢ PreservesLimitsOfShape (Discrete J) F

Next tactic:
classical
    let e := Fintype.equivFin J
    haveI := preservesShapeFinOfPreservesBinaryAndTerminal F (Fintype.card J)
    apply preservesLimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence e).symm
/-- If `F` preserves the terminal object and binary products then it preserves finite products. -/
def preservesFiniteProductsOfPreservesBinaryAndTerminal (J : Type) [Fintype J] :
    PreservesLimitsOfShape (Discrete J) F := by
  classical
    

Proof state:
J✝ : Type v
inst✝⁶ : SmallCategory J✝
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
F : C ⥤ D
inst✝³ : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝² : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝¹ : HasFiniteProducts C
J : Type
inst✝ : Fintype J
⊢ PreservesLimitsOfShape (Discrete J) F

Next tactic:
let e := Fintype.equivFin J
/-- If `F` preserves the terminal object and binary products then it preserves finite products. -/
def preservesFiniteProductsOfPreservesBinaryAndTerminal (J : Type) [Fintype J] :
    PreservesLimitsOfShape (Discrete J) F := by
  classical
    let e := Fintype.equivFin J
    

Proof state:
J✝ : Type v
inst✝⁶ : SmallCategory J✝
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
F : C ⥤ D
inst✝³ : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝² : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝¹ : HasFiniteProducts C
J : Type
inst✝ : Fintype J
e : J ≃ Fin (Fintype.card J) := Fintype.equivFin J
⊢ PreservesLimitsOfShape (Discrete J) F

Next tactic:
haveI := preservesShapeFinOfPreservesBinaryAndTerminal F (Fintype.card J)
/-- If `F` preserves the terminal object and binary products then it preserves finite products. -/
def preservesFiniteProductsOfPreservesBinaryAndTerminal (J : Type) [Fintype J] :
    PreservesLimitsOfShape (Discrete J) F := by
  classical
    let e := Fintype.equivFin J
    haveI := preservesShapeFinOfPreservesBinaryAndTerminal F (Fintype.card J)
    

Proof state:
J✝ : Type v
inst✝⁶ : SmallCategory J✝
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u'
inst✝⁴ : Category.{v', u'} D
F : C ⥤ D
inst✝³ : PreservesLimitsOfShape (Discrete WalkingPair) F
inst✝² : PreservesLimitsOfShape (Discrete PEmpty.{1}) F
inst✝¹ : HasFiniteProducts C
J : Type
inst✝ : Fintype J
e : J ≃ Fin (Fintype.card J) := Fintype.equivFin J
this : PreservesLimitsOfShape (Discrete (Fin (Fintype.card J))) F
⊢ PreservesLimitsOfShape (Discrete J) F

Next tactic:
apply preservesLimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence e).symm
/-- Given `n+1` objects of `C`, a cofan for the last `n` with point `c₁.pt`
and a binary cofan on `c₁.X` and `f 0`, we can build a cofan for all `n+1`.

In `extendCofanIsColimit` we show that if the two given cofans are colimits,
then this cofan is also a colimit.
-/

@[simps!] -- Porting note: removed semireducible config
def extendCofan {n : ℕ} {f : Fin (n + 1) → C} (c₁ : Cofan fun i : Fin n => f i.succ)
    (c₂ : BinaryCofan (f 0) c₁.pt) : Cofan f :=
  Cofan.mk c₂.pt
    (by
      

Proof state:
J : Type v
inst✝² : SmallCategory J
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
n : ℕ
f : Fin (n + 1) → C
c₁ : Cofan fun i => f (Fin.succ i)
c₂ : BinaryCofan (f 0) c₁.pt
⊢ (b : Fin (n + 1)) → f b ⟶ c₂.pt

Next tactic:
refine' Fin.cases _ _
/-- Given `n+1` objects of `C`, a cofan for the last `n` with point `c₁.pt`
and a binary cofan on `c₁.X` and `f 0`, we can build a cofan for all `n+1`.

In `extendCofanIsColimit` we show that if the two given cofans are colimits,
then this cofan is also a colimit.
-/

@[simps!] -- Porting note: removed semireducible config
def extendCofan {n : ℕ} {f : Fin (n + 1) → C} (c₁ : Cofan fun i : Fin n => f i.succ)
    (c₂ : BinaryCofan (f 0) c₁.pt) : Cofan f :=
  Cofan.mk c₂.pt
    (by
      refine' Fin.cases _ _
      · 

Proof state:
case refine'_1
J : Type v
inst✝² : SmallCategory J
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
n : ℕ
f : Fin (n + 1) → C
c₁ : Cofan fun i => f (Fin.succ i)
c₂ : BinaryCofan (f 0) c₁.pt
⊢ f 0 ⟶ c₂.pt

Next tactic:
apply c₂.inl
/-- Given `n+1` objects of `C`, a cofan for the last `n` with point `c₁.pt`
and a binary cofan on `c₁.X` and `f 0`, we can build a cofan for all `n+1`.

In `extendCofanIsColimit` we show that if the two given cofans are colimits,
then this cofan is also a colimit.
-/

@[simps!] -- Porting note: removed semireducible config
def extendCofan {n : ℕ} {f : Fin (n + 1) → C} (c₁ : Cofan fun i : Fin n => f i.succ)
    (c₂ : BinaryCofan (f 0) c₁.pt) : Cofan f :=
  Cofan.mk c₂.pt
    (by
      refine' Fin.cases _ _
      · apply c₂.inl
      · 

Proof state:
case refine'_2
J : Type v
inst✝² : SmallCategory J
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
n : ℕ
f : Fin (n + 1) → C
c₁ : Cofan fun i => f (Fin.succ i)
c₂ : BinaryCofan (f 0) c₁.pt
⊢ (i : Fin n) → f (Fin.succ i) ⟶ c₂.pt

Next tactic:
intro i
/-- Given `n+1` objects of `C`, a cofan for the last `n` with point `c₁.pt`
and a binary cofan on `c₁.X` and `f 0`, we can build a cofan for all `n+1`.

In `extendCofanIsColimit` we show that if the two given cofans are colimits,
then this cofan is also a colimit.
-/

@[simps!] -- Porting note: removed semireducible config
def extendCofan {n : ℕ} {f : Fin (n + 1) → C} (c₁ : Cofan fun i : Fin n => f i.succ)
    (c₂ : BinaryCofan (f 0) c₁.pt) : Cofan f :=
  Cofan.mk c₂.pt
    (by
      refine' Fin.cases _ _
      · apply c₂.inl
      · intro i
        

Proof state:
case refine'_2
J : Type v
inst✝² : SmallCategory J
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
n : ℕ
f : Fin (n + 1) → C
c₁ : Cofan fun i => f (Fin.succ i)
c₂ : BinaryCofan (f 0) c₁.pt
i : Fin n
⊢ f (Fin.succ i) ⟶ c₂.pt

Next tactic:
apply c₁.ι.app ⟨i⟩ ≫ c₂.inr
/-- Show that if the two given cofans in `extendCofan` are colimits,
then the constructed cofan is also a colimit.
-/
def extendCofanIsColimit {n : ℕ} (f : Fin (n + 1) → C) {c₁ : Cofan fun i : Fin n => f i.succ}
    {c₂ : BinaryCofan (f 0) c₁.pt} (t₁ : IsColimit c₁) (t₂ : IsColimit c₂) :
    IsColimit (extendCofan c₁ c₂) where
  desc s := by
    

Proof state:
J : Type v
inst✝² : SmallCategory J
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
n : ℕ
f : Fin (n + 1) → C
c₁ : Cofan fun i => f (Fin.succ i)
c₂ : BinaryCofan (f 0) c₁.pt
t₁ : IsColimit c₁
t₂ : IsColimit c₂
s : Cocone (Discrete.functor f)
⊢ (extendCofan c₁ c₂).pt ⟶ s.pt

Next tactic:
apply (BinaryCofan.IsColimit.desc' t₂ (s.ι.app ⟨0⟩) _).1
/-- Show that if the two given cofans in `extendCofan` are colimits,
then the constructed cofan is also a colimit.
-/
def extendCofanIsColimit {n : ℕ} (f : Fin (n + 1) → C) {c₁ : Cofan fun i : Fin n => f i.succ}
    {c₂ : BinaryCofan (f 0) c₁.pt} (t₁ : IsColimit c₁) (t₂ : IsColimit c₂) :
    IsColimit (extendCofan c₁ c₂) where
  desc s := by
    apply (BinaryCofan.IsColimit.desc' t₂ (s.ι.app ⟨0⟩) _).1
    

Proof state:
J : Type v
inst✝² : SmallCategory J
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u'
inst✝ : Category.{v', u'} D
n : ℕ
f : Fin (n + 1) → C
c₁ : Cofan fun i => f (Fin.succ i)
c₂ : BinaryCofan (f 0) c₁.pt
t₁ : IsColimit c₁
t₂ : IsColimit c₂
s : Cocone (Discrete.functor f)
⊢ c₁.pt ⟶ ((Functor.const (Discrete (Fin (n + 1)))).obj s.pt).obj { as := 0 }

Next tactic:
apply t₁.desc ⟨_, Discrete.natTrans fun i => s.ι.app ⟨i.as.succ⟩⟩