l3lab/ntp-mathlib huggingface dataset:
/--
If `C` has an initial object and binary coproducts, then it has a coproduct for objects indexed by
`Fin n`.
This is a helper lemma for `hasCofiniteProductsOfHasBinaryAndTerminal`, which is more general
than this.
-/
private theorem hasCoproduct_fin : ∀ (n : ℕ) (f : Fin n → C), HasCoproduct f
  | 0 => fun 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
inst✝¹ : HasBinaryCoproducts C
inst✝ : HasInitial C
f : Fin 0 → C
⊢ HasCoproduct f

Next tactic:
letI : HasColimitsOfShape (Discrete (Fin 0)) C :=
      hasColimitsOfShape_of_equivalence (Discrete.equivalence.{0} finZeroEquiv'.symm)
/--
If `C` has an initial object and binary coproducts, then it has a coproduct for objects indexed by
`Fin n`.
This is a helper lemma for `hasCofiniteProductsOfHasBinaryAndTerminal`, which is more general
than this.
-/
private theorem hasCoproduct_fin : ∀ (n : ℕ) (f : Fin n → C), HasCoproduct f
  | 0 => fun f => by
    letI : HasColimitsOfShape (Discrete (Fin 0)) C :=
      hasColimitsOfShape_of_equivalence (Discrete.equivalence.{0} finZeroEquiv'.symm)
    

Proof state:
J : Type v
inst✝⁴ : SmallCategory J
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasBinaryCoproducts C
inst✝ : HasInitial C
f : Fin 0 → C
this : HasColimitsOfShape (Discrete (Fin 0)) C :=
  hasColimitsOfShape_of_equivalence (Discrete.equivalence finZeroEquiv'.symm)
⊢ HasCoproduct f

Next tactic:
infer_instance
/--
If `C` has an initial object and binary coproducts, then it has a coproduct for objects indexed by
`Fin n`.
This is a helper lemma for `hasCofiniteProductsOfHasBinaryAndTerminal`, which is more general
than this.
-/
private theorem hasCoproduct_fin : ∀ (n : ℕ) (f : Fin n → C), HasCoproduct f
  | 0 => fun f => by
    letI : HasColimitsOfShape (Discrete (Fin 0)) C :=
      hasColimitsOfShape_of_equivalence (Discrete.equivalence.{0} finZeroEquiv'.symm)
    infer_instance
  | n + 1 => fun 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
inst✝¹ : HasBinaryCoproducts C
inst✝ : HasInitial C
n : ℕ
f : Fin (n + 1) → C
⊢ HasCoproduct f

Next tactic:
haveI := hasCoproduct_fin n
/--
If `C` has an initial object and binary coproducts, then it has a coproduct for objects indexed by
`Fin n`.
This is a helper lemma for `hasCofiniteProductsOfHasBinaryAndTerminal`, which is more general
than this.
-/
private theorem hasCoproduct_fin : ∀ (n : ℕ) (f : Fin n → C), HasCoproduct f
  | 0 => fun f => by
    letI : HasColimitsOfShape (Discrete (Fin 0)) C :=
      hasColimitsOfShape_of_equivalence (Discrete.equivalence.{0} finZeroEquiv'.symm)
    infer_instance
  | n + 1 => fun f => by
    haveI := hasCoproduct_fin 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
inst✝¹ : HasBinaryCoproducts C
inst✝ : HasInitial C
n : ℕ
f : Fin (n + 1) → C
this : ∀ (f : Fin n → C), HasCoproduct f
⊢ HasCoproduct f

Next tactic:
apply
      HasColimit.mk ⟨_, extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)⟩
/-- If `C` has an initial object and binary coproducts, then it has finite coproducts. -/
theorem hasFiniteCoproducts_of_has_binary_and_initial : HasFiniteCoproducts C := 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
inst✝¹ : HasBinaryCoproducts C
inst✝ : HasInitial C
⊢ HasFiniteCoproducts C

Next tactic:
refine' ⟨fun n => ⟨fun K => _⟩⟩
/-- If `C` has an initial object and binary coproducts, then it has finite coproducts. -/
theorem hasFiniteCoproducts_of_has_binary_and_initial : HasFiniteCoproducts C := by
  refine' ⟨fun n => ⟨fun K => _⟩⟩
  

Proof state:
J : Type v
inst✝⁴ : SmallCategory J
C : Type u
inst✝³ : Category.{v, u} C
D : Type u'
inst✝² : Category.{v', u'} D
inst✝¹ : HasBinaryCoproducts C
inst✝ : HasInitial C
n : ℕ
K : Discrete (Fin n) ⥤ C
⊢ HasColimit K

Next tactic:
letI := hasCoproduct_fin n fun n => K.obj ⟨n⟩
/-- If `C` has an initial object and binary coproducts, then it has finite coproducts. -/
theorem hasFiniteCoproducts_of_has_binary_and_initial : HasFiniteCoproducts C := by
  refine' ⟨fun n => ⟨fun K => _⟩⟩
  letI := hasCoproduct_fin 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
inst✝¹ : HasBinaryCoproducts C
inst✝ : HasInitial C
n : ℕ
K : Discrete (Fin n) ⥤ C
this : HasCoproduct fun n_1 => K.obj { as := n_1 } := CategoryTheory.hasCoproduct_fin n fun n_1 => K.obj { as := n_1 }
⊢ HasColimit K

Next tactic:
let that : K ≅ Discrete.functor fun n => K.obj ⟨n⟩ := Discrete.natIso fun ⟨i⟩ => Iso.refl _
/-- If `C` has an initial object and binary coproducts, then it has finite coproducts. -/
theorem hasFiniteCoproducts_of_has_binary_and_initial : HasFiniteCoproducts C := by
  refine' ⟨fun n => ⟨fun K => _⟩⟩
  letI := hasCoproduct_fin n fun n => K.obj ⟨n⟩
  let that : K ≅ Discrete.functor fun n => K.obj ⟨n⟩ := 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
inst✝¹ : HasBinaryCoproducts C
inst✝ : HasInitial C
n : ℕ
K : Discrete (Fin n) ⥤ C
this : HasCoproduct fun n_1 => K.obj { as := n_1 } := CategoryTheory.hasCoproduct_fin n fun n_1 => K.obj { as := n_1 }
that : K ≅ Discrete.functor fun n_1 => K.obj { as := n_1 } :=
  Discrete.natIso fun x =>
    match x with
    | { as := i } => Iso.refl (K.obj { as := i })
⊢ HasColimit K

Next tactic:
apply @hasColimitOfIso _ _ _ _ _ _ this that
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun 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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
f : Fin 0 → C
⊢ PreservesColimit (Discrete.functor f) F

Next tactic:
letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    

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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
f : Fin 0 → C
this : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
  preservesColimitsOfShapeOfEquiv (Discrete.equivalence finZeroEquiv'.symm) F
⊢ PreservesColimit (Discrete.functor f) F

Next tactic:
infer_instance
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => 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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
⊢ (f : Fin (n + 1) → C) → PreservesColimit (Discrete.functor f) F

Next tactic:
haveI := preservesFinOfPreservesBinaryAndInitial n
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial 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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
⊢ (f : Fin (n + 1) → C) → PreservesColimit (Discrete.functor f) F

Next tactic:
intro f
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial n
    intro 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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
f : Fin (n + 1) → C
⊢ PreservesColimit (Discrete.functor f) F

Next tactic:
refine'
      preservesColimitOfPreservesColimitCocone
        (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial n
    intro f
    refine'
      preservesColimitOfPreservesColimitCocone
        (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _
    

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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
f : Fin (n + 1) → C
⊢ IsColimit
    (F.mapCocone
      (extendCofan (colimit.cocone (Discrete.functor fun i => f (Fin.succ i)))
        (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt))))

Next tactic:
apply (isColimitMapCoconeCofanMkEquiv _ _ _).symm _
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial n
    intro f
    refine'
      preservesColimitOfPreservesColimitCocone
        (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _
    apply (isColimitMapCoconeCofanMkEquiv _ _ _).symm _
    

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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
f : Fin (n + 1) → C
⊢ IsColimit
    (Cofan.mk (F.obj (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt)
      fun j =>
      F.map
        (Fin.cases
          (BinaryCofan.inl (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
          (fun i =>
            (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).ι.app { as := i } ≫
              BinaryCofan.inr
                (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
          j))

Next tactic:
let this :=
      extendCofanIsColimit (fun i => F.obj (f i))
        (isColimitOfHasCoproductOfPreservesColimit F _)
        (isColimitOfHasBinaryCoproductOfPreservesColimit F _ _)
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial n
    intro f
    refine'
      preservesColimitOfPreservesColimitCocone
        (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _
    apply (isColimitMapCoconeCofanMkEquiv _ _ _).symm _
    let this :=
      extendCofanIsColimit (fun i => F.obj (f i))
        (isColimitOfHasCoproductOfPreservesColimit F _)
        (isColimitOfHasBinaryCoproductOfPreservesColimit 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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsColimit
  (extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
    (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))) :=
  extendCofanIsColimit (fun i => F.obj (f i)) (isColimitOfHasCoproductOfPreservesColimit F fun i => f (Fin.succ i))
    (isColimitOfHasBinaryCoproductOfPreservesColimit F (f 0) (∐ fun i => f (Fin.succ i)))
⊢ IsColimit
    (Cofan.mk (F.obj (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt)
      fun j =>
      F.map
        (Fin.cases
          (BinaryCofan.inl (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
          (fun i =>
            (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).ι.app { as := i } ≫
              BinaryCofan.inr
                (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
          j))

Next tactic:
refine' IsColimit.ofIsoColimit this _
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial n
    intro f
    refine'
      preservesColimitOfPreservesColimitCocone
        (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _
    apply (isColimitMapCoconeCofanMkEquiv _ _ _).symm _
    let this :=
      extendCofanIsColimit (fun i => F.obj (f i))
        (isColimitOfHasCoproductOfPreservesColimit F _)
        (isColimitOfHasBinaryCoproductOfPreservesColimit F _ _)
    refine' IsColimit.ofIsoColimit 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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsColimit
  (extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
    (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))) :=
  extendCofanIsColimit (fun i => F.obj (f i)) (isColimitOfHasCoproductOfPreservesColimit F fun i => f (Fin.succ i))
    (isColimitOfHasBinaryCoproductOfPreservesColimit F (f 0) (∐ fun i => f (Fin.succ i)))
⊢ extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
      (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr)) ≅
    Cofan.mk (F.obj (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt)
      fun j =>
      F.map
        (Fin.cases
          (BinaryCofan.inl (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
          (fun i =>
            (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).ι.app { as := i } ≫
              BinaryCofan.inr
                (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
          j)

Next tactic:
apply Cocones.ext _ _
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial n
    intro f
    refine'
      preservesColimitOfPreservesColimitCocone
        (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _
    apply (isColimitMapCoconeCofanMkEquiv _ _ _).symm _
    let this :=
      extendCofanIsColimit (fun i => F.obj (f i))
        (isColimitOfHasCoproductOfPreservesColimit F _)
        (isColimitOfHasBinaryCoproductOfPreservesColimit F _ _)
    refine' IsColimit.ofIsoColimit this _
    apply Cocones.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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsColimit
  (extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
    (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))) :=
  extendCofanIsColimit (fun i => F.obj (f i)) (isColimitOfHasCoproductOfPreservesColimit F fun i => f (Fin.succ i))
    (isColimitOfHasBinaryCoproductOfPreservesColimit F (f 0) (∐ fun i => f (Fin.succ i)))
⊢ ∀ (j : Discrete (Fin (n + 1))),
    (extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
                (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))).ι.app
          j ≫
        (Iso.refl
            (extendCofan
                (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
                (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))).pt).hom =
      (Cofan.mk (F.obj (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt)
              fun j =>
              F.map
                (Fin.cases
                  (BinaryCofan.inl
                    (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                  (fun i =>
                    (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).ι.app { as := i } ≫
                      BinaryCofan.inr
                        (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                  j)).ι.app
        j

Next tactic:
rintro ⟨j⟩
/-- If `F` preserves the initial object and binary coproducts, then it preserves products indexed by
`Fin n` for any `n`.
-/
noncomputable def preservesFinOfPreservesBinaryAndInitial :
    ∀ (n : ℕ) (f : Fin n → C), PreservesColimit (Discrete.functor f) F
  | 0 => fun f => by
    letI : PreservesColimitsOfShape (Discrete (Fin 0)) F :=
      preservesColimitsOfShapeOfEquiv.{0, 0} (Discrete.equivalence finZeroEquiv'.symm) _
    infer_instance
  | n + 1 => by
    haveI := preservesFinOfPreservesBinaryAndInitial n
    intro f
    refine'
      preservesColimitOfPreservesColimitCocone
        (extendCofanIsColimit f (colimit.isColimit _) (colimit.isColimit _)) _
    apply (isColimitMapCoconeCofanMkEquiv _ _ _).symm _
    let this :=
      extendCofanIsColimit (fun i => F.obj (f i))
        (isColimitOfHasCoproductOfPreservesColimit F _)
        (isColimitOfHasBinaryCoproductOfPreservesColimit F _ _)
    refine' IsColimit.ofIsoColimit this _
    apply Cocones.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✝² : PreservesColimitsOfShape (Discrete WalkingPair) F
inst✝¹ : PreservesColimitsOfShape (Discrete PEmpty.{1}) F
inst✝ : HasFiniteCoproducts C
n : ℕ
this✝ : (f : Fin n → C) → PreservesColimit (Discrete.functor f) F
f : Fin (n + 1) → C
this : IsColimit
  (extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
    (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))) :=
  extendCofanIsColimit (fun i => F.obj (f i)) (isColimitOfHasCoproductOfPreservesColimit F fun i => f (Fin.succ i))
    (isColimitOfHasBinaryCoproductOfPreservesColimit F (f 0) (∐ fun i => f (Fin.succ i)))
j : Fin (n + 1)
⊢ (extendCofan (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
              (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))).ι.app
        { as := j } ≫
      (Iso.refl
          (extendCofan
              (Cofan.mk (F.obj (∐ fun i => f (Fin.succ i))) fun j => F.map (Sigma.ι (fun i => f (Fin.succ i)) j))
              (BinaryCofan.mk (F.map coprod.inl) (F.map coprod.inr))).pt).hom =
    (Cofan.mk (F.obj (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)).pt)
            fun j =>
            F.map
              (Fin.cases
                (BinaryCofan.inl
                  (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                (fun i =>
                  (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).ι.app { as := i } ≫
                    BinaryCofan.inr
                      (colimit.cocone (pair (f 0) (colimit.cocone (Discrete.functor fun i => f (Fin.succ i))).pt)))
                j)).ι.app
      { as := j }

Next tactic:
refine' Fin.inductionOn j ?_ ?_