l3lab/ntp-mathlib huggingface dataset:
/--
The two parallel maps in the equalizer diagram for the sheaf condition corresponding to the
inclusion maps in a disjoint coproduct are equal.
-/
theorem firstMap_eq_secondMap : Equalizer.Presieve.Arrows.firstMap F X c.inj =
    Equalizer.Presieve.Arrows.secondMap F X c.inj := by
  ext a ⟨i, j⟩
  simp only [Equalizer.Presieve.Arrows.firstMap, Types.pi_lift_π_apply, types_comp_apply,
    Equalizer.Presieve.Arrows.secondMap]
  by_cases hi : i = j
  · rw [hi, Mono.right_cancellation _ _ pullback.condition]
  · have := preservesTerminalOfIsSheafForEmpty F hF hI
    

Proof state:
case neg
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
a : Equalizer.Presieve.Arrows.FirstObj F X
i j : α
hi : ¬i = j
this : PreservesLimit (Functor.empty Cᵒᵖ) F
⊢ F.map pullback.fst.op (Pi.π (fun i => F.obj (op (X i))) i a) =
    F.map pullback.snd.op (Pi.π (fun i => F.obj (op (X i))) j a)

Next tactic:
apply_fun (F.mapIso ((hd i j hi).isoPullback).op ≪≫ F.mapIso (terminalIsoIsTerminal
      (terminalOpOfInitial initialIsInitial)).symm ≪≫ (PreservesTerminal.iso F)).hom using
      injective_of_mono _
/--
The two parallel maps in the equalizer diagram for the sheaf condition corresponding to the
inclusion maps in a disjoint coproduct are equal.
-/
theorem firstMap_eq_secondMap : Equalizer.Presieve.Arrows.firstMap F X c.inj =
    Equalizer.Presieve.Arrows.secondMap F X c.inj := by
  ext a ⟨i, j⟩
  simp only [Equalizer.Presieve.Arrows.firstMap, Types.pi_lift_π_apply, types_comp_apply,
    Equalizer.Presieve.Arrows.secondMap]
  by_cases hi : i = j
  · rw [hi, Mono.right_cancellation _ _ pullback.condition]
  · have := preservesTerminalOfIsSheafForEmpty F hF hI
    apply_fun (F.mapIso ((hd i j hi).isoPullback).op ≪≫ F.mapIso (terminalIsoIsTerminal
      (terminalOpOfInitial initialIsInitial)).symm ≪≫ (PreservesTerminal.iso F)).hom using
      injective_of_mono _
    

Proof state:
case neg
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
a : Equalizer.Presieve.Arrows.FirstObj F X
i j : α
hi : ¬i = j
this : PreservesLimit (Functor.empty Cᵒᵖ) F
⊢ (F.mapIso
            (Iso.op
              (IsPullback.isoPullback
                (_ : IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)))) ≪≫
          F.mapIso (terminalIsoIsTerminal (terminalOpOfInitial initialIsInitial)).symm ≪≫ PreservesTerminal.iso F).hom
      (F.map pullback.fst.op (Pi.π (fun i => F.obj (op (X i))) i a)) =
    (F.mapIso
            (Iso.op
              (IsPullback.isoPullback
                (_ : IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)))) ≪≫
          F.mapIso (terminalIsoIsTerminal (terminalOpOfInitial initialIsInitial)).symm ≪≫ PreservesTerminal.iso F).hom
      (F.map pullback.snd.op (Pi.π (fun i => F.obj (op (X i))) j a))

Next tactic:
ext ⟨i⟩
/--
The two parallel maps in the equalizer diagram for the sheaf condition corresponding to the
inclusion maps in a disjoint coproduct are equal.
-/
theorem firstMap_eq_secondMap : Equalizer.Presieve.Arrows.firstMap F X c.inj =
    Equalizer.Presieve.Arrows.secondMap F X c.inj := by
  ext a ⟨i, j⟩
  simp only [Equalizer.Presieve.Arrows.firstMap, Types.pi_lift_π_apply, types_comp_apply,
    Equalizer.Presieve.Arrows.secondMap]
  by_cases hi : i = j
  · rw [hi, Mono.right_cancellation _ _ pullback.condition]
  · have := preservesTerminalOfIsSheafForEmpty F hF hI
    apply_fun (F.mapIso ((hd i j hi).isoPullback).op ≪≫ F.mapIso (terminalIsoIsTerminal
      (terminalOpOfInitial initialIsInitial)).symm ≪≫ (PreservesTerminal.iso F)).hom using
      injective_of_mono _
    ext ⟨i⟩
    

Proof state:
case neg.w.mk
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
a : Equalizer.Presieve.Arrows.FirstObj F X
i✝ j : α
hi : ¬i✝ = j
this : PreservesLimit (Functor.empty Cᵒᵖ) F
i : PEmpty.{1}
⊢ limit.π (Functor.empty (Type (max u v))) { as := i }
      ((F.mapIso
              (Iso.op
                (IsPullback.isoPullback
                  (_ : IsPullback (initial.to (X i✝)) (initial.to (X j)) (Cofan.inj c i✝) (Cofan.inj c j)))) ≪≫
            F.mapIso (terminalIsoIsTerminal (terminalOpOfInitial initialIsInitial)).symm ≪≫ PreservesTerminal.iso F).hom
        (F.map pullback.fst.op (Pi.π (fun i => F.obj (op (X i))) i✝ a))) =
    limit.π (Functor.empty (Type (max u v))) { as := i }
      ((F.mapIso
              (Iso.op
                (IsPullback.isoPullback
                  (_ : IsPullback (initial.to (X i✝)) (initial.to (X j)) (Cofan.inj c i✝) (Cofan.inj c j)))) ≪≫
            F.mapIso (terminalIsoIsTerminal (terminalOpOfInitial initialIsInitial)).symm ≪≫ PreservesTerminal.iso F).hom
        (F.map pullback.snd.op (Pi.π (fun i => F.obj (op (X i))) j a)))

Next tactic:
exact i.elim
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
⊢ let_fun this := (_ : HasColimit (Discrete.functor X));
  (piComparison F fun x => op (X x)) =
    F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
      Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c)

Next tactic:
have : HasCoproduct X := ⟨⟨c, hc⟩⟩
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
this : HasCoproduct X
⊢ let_fun this := (_ : HasColimit (Discrete.functor X));
  (piComparison F fun x => op (X x)) =
    F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
      Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c)

Next tactic:
dsimp only [Equalizer.Presieve.Arrows.forkMap]
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  dsimp only [Equalizer.Presieve.Arrows.forkMap]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
this : HasCoproduct X
⊢ (piComparison F fun x => op (X x)) =
    F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
      Pi.lift fun i => F.map (Cofan.inj c i).op

Next tactic:
have h : Pi.lift (fun i ↦ F.map (c.inj i).op) =
      F.map (Pi.lift (fun i ↦ (c.inj i).op)) ≫ piComparison F _ := by simp
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  dsimp only [Equalizer.Presieve.Arrows.forkMap]
  have h : Pi.lift (fun i ↦ F.map (c.inj i).op) =
      F.map (Pi.lift (fun i ↦ (c.inj i).op)) ≫ piComparison F _ := by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
this : HasCoproduct X
⊢ (Pi.lift fun i => F.map (Cofan.inj c i).op) =
    F.map (Pi.lift fun i => (Cofan.inj c i).op) ≫ piComparison F fun i => op (X i)

Next tactic:
simp
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  dsimp only [Equalizer.Presieve.Arrows.forkMap]
  have h : Pi.lift (fun i ↦ F.map (c.inj i).op) =
      F.map (Pi.lift (fun i ↦ (c.inj i).op)) ≫ piComparison F _ := by simp
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
this : HasCoproduct X
h :
  (Pi.lift fun i => F.map (Cofan.inj c i).op) =
    F.map (Pi.lift fun i => (Cofan.inj c i).op) ≫ piComparison F fun i => op (X i)
⊢ (piComparison F fun x => op (X x)) =
    F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
      Pi.lift fun i => F.map (Cofan.inj c i).op

Next tactic:
rw [h, ← Category.assoc, ← Functor.map_comp]
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  dsimp only [Equalizer.Presieve.Arrows.forkMap]
  have h : Pi.lift (fun i ↦ F.map (c.inj i).op) =
      F.map (Pi.lift (fun i ↦ (c.inj i).op)) ≫ piComparison F _ := by simp
  rw [h, ← Category.assoc, ← Functor.map_comp]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
this : HasCoproduct X
h :
  (Pi.lift fun i => F.map (Cofan.inj c i).op) =
    F.map (Pi.lift fun i => (Cofan.inj c i).op) ≫ piComparison F fun i => op (X i)
⊢ (piComparison F fun x => op (X x)) =
    F.map ((opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫ Pi.lift fun i => (Cofan.inj c i).op) ≫
      piComparison F fun i => op (X i)

Next tactic:
have hh : Pi.lift (fun i ↦ (c.inj i).op) = (productIsProduct (op <| X ·)).lift c.op := by
    simp [Pi.lift, productIsProduct]
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  dsimp only [Equalizer.Presieve.Arrows.forkMap]
  have h : Pi.lift (fun i ↦ F.map (c.inj i).op) =
      F.map (Pi.lift (fun i ↦ (c.inj i).op)) ≫ piComparison F _ := by simp
  rw [h, ← Category.assoc, ← Functor.map_comp]
  have hh : Pi.lift (fun i ↦ (c.inj i).op) = (productIsProduct (op <| X ·)).lift c.op := by
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
this : HasCoproduct X
h :
  (Pi.lift fun i => F.map (Cofan.inj c i).op) =
    F.map (Pi.lift fun i => (Cofan.inj c i).op) ≫ piComparison F fun i => op (X i)
⊢ (Pi.lift fun i => (Cofan.inj c i).op) = IsLimit.lift (productIsProduct fun x => op (X x)) (Cofan.op c)

Next tactic:
simp [Pi.lift, productIsProduct]
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  dsimp only [Equalizer.Presieve.Arrows.forkMap]
  have h : Pi.lift (fun i ↦ F.map (c.inj i).op) =
      F.map (Pi.lift (fun i ↦ (c.inj i).op)) ≫ piComparison F _ := by simp
  rw [h, ← Category.assoc, ← Functor.map_comp]
  have hh : Pi.lift (fun i ↦ (c.inj i).op) = (productIsProduct (op <| X ·)).lift c.op := by
    simp [Pi.lift, productIsProduct]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
this : HasCoproduct X
h :
  (Pi.lift fun i => F.map (Cofan.inj c i).op) =
    F.map (Pi.lift fun i => (Cofan.inj c i).op) ≫ piComparison F fun i => op (X i)
hh : (Pi.lift fun i => (Cofan.inj c i).op) = IsLimit.lift (productIsProduct fun x => op (X x)) (Cofan.op c)
⊢ (piComparison F fun x => op (X x)) =
    F.map ((opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫ Pi.lift fun i => (Cofan.inj c i).op) ≫
      piComparison F fun i => op (X i)

Next tactic:
rw [hh, ← desc_op_comp_opCoproductIsoProduct'_hom hc]
theorem piComparison_fac :
    have : HasCoproduct X := ⟨⟨c, hc⟩⟩
    piComparison F (fun x ↦ op (X x)) = F.map (opCoproductIsoProduct' hc (productIsProduct _)).inv ≫
    Equalizer.Presieve.Arrows.forkMap F X c.inj := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  dsimp only [Equalizer.Presieve.Arrows.forkMap]
  have h : Pi.lift (fun i ↦ F.map (c.inj i).op) =
      F.map (Pi.lift (fun i ↦ (c.inj i).op)) ≫ piComparison F _ := by simp
  rw [h, ← Category.assoc, ← Functor.map_comp]
  have hh : Pi.lift (fun i ↦ (c.inj i).op) = (productIsProduct (op <| X ·)).lift c.op := by
    simp [Pi.lift, productIsProduct]
  rw [hh, ← desc_op_comp_opCoproductIsoProduct'_hom hc]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
this : HasCoproduct X
h :
  (Pi.lift fun i => F.map (Cofan.inj c i).op) =
    F.map (Pi.lift fun i => (Cofan.inj c i).op) ≫ piComparison F fun i => op (X i)
hh : (Pi.lift fun i => (Cofan.inj c i).op) = IsLimit.lift (productIsProduct fun x => op (X x)) (Cofan.op c)
⊢ (piComparison F fun x => op (X x)) =
    F.map
        ((opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
          (IsColimit.desc hc c).op ≫ (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).hom) ≫
      piComparison F fun i => op (X i)

Next tactic:
simp
/--
If `F` is a presheaf which `IsSheafFor` a presieve of arrows and the empty presieve, then it
preserves the product corresponding to the presieve of arrows.
-/
noncomputable
def preservesProductOfIsSheafFor (hF' : (ofArrows X c.inj).IsSheafFor F) :
    PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
hF' : IsSheafFor F (ofArrows X (Cofan.inj c))
⊢ PreservesLimit (Discrete.functor fun x => op (X x)) F

Next tactic:
have : HasCoproduct X := ⟨⟨c, hc⟩⟩
/--
If `F` is a presheaf which `IsSheafFor` a presieve of arrows and the empty presieve, then it
preserves the product corresponding to the presieve of arrows.
-/
noncomputable
def preservesProductOfIsSheafFor (hF' : (ofArrows X c.inj).IsSheafFor F) :
    PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
hF' : IsSheafFor F (ofArrows X (Cofan.inj c))
this : HasCoproduct X
⊢ PreservesLimit (Discrete.functor fun x => op (X x)) F

Next tactic:
refine @PreservesProduct.ofIsoComparison _ _ _ _ F _ (fun x ↦ op (X x)) _ _ ?_
/--
If `F` is a presheaf which `IsSheafFor` a presieve of arrows and the empty presieve, then it
preserves the product corresponding to the presieve of arrows.
-/
noncomputable
def preservesProductOfIsSheafFor (hF' : (ofArrows X c.inj).IsSheafFor F) :
    PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  refine @PreservesProduct.ofIsoComparison _ _ _ _ F _ (fun x ↦ op (X x)) _ _ ?_
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
hF' : IsSheafFor F (ofArrows X (Cofan.inj c))
this : HasCoproduct X
⊢ IsIso (piComparison F fun x => op (X x))

Next tactic:
rw [piComparison_fac (hc := hc)]
/--
If `F` is a presheaf which `IsSheafFor` a presieve of arrows and the empty presieve, then it
preserves the product corresponding to the presieve of arrows.
-/
noncomputable
def preservesProductOfIsSheafFor (hF' : (ofArrows X c.inj).IsSheafFor F) :
    PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  refine @PreservesProduct.ofIsoComparison _ _ _ _ F _ (fun x ↦ op (X x)) _ _ ?_
  rw [piComparison_fac (hc := hc)]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
hF' : IsSheafFor F (ofArrows X (Cofan.inj c))
this : HasCoproduct X
⊢ IsIso
    (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
      Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))

Next tactic:
refine @IsIso.comp_isIso _ _ _ _ _ _ _ inferInstance ?_
/--
If `F` is a presheaf which `IsSheafFor` a presieve of arrows and the empty presieve, then it
preserves the product corresponding to the presieve of arrows.
-/
noncomputable
def preservesProductOfIsSheafFor (hF' : (ofArrows X c.inj).IsSheafFor F) :
    PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  refine @PreservesProduct.ofIsoComparison _ _ _ _ F _ (fun x ↦ op (X x)) _ _ ?_
  rw [piComparison_fac (hc := hc)]
  refine @IsIso.comp_isIso _ _ _ _ _ _ _ inferInstance ?_
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
hF' : IsSheafFor F (ofArrows X (Cofan.inj c))
this : HasCoproduct X
⊢ IsIso (Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))

Next tactic:
rw [isIso_iff_bijective, Function.bijective_iff_existsUnique]
/--
If `F` is a presheaf which `IsSheafFor` a presieve of arrows and the empty presieve, then it
preserves the product corresponding to the presieve of arrows.
-/
noncomputable
def preservesProductOfIsSheafFor (hF' : (ofArrows X c.inj).IsSheafFor F) :
    PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F := by
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  refine @PreservesProduct.ofIsoComparison _ _ _ _ F _ (fun x ↦ op (X x)) _ _ ?_
  rw [piComparison_fac (hc := hc)]
  refine @IsIso.comp_isIso _ _ _ _ _ _ _ inferInstance ?_
  rw [isIso_iff_bijective, Function.bijective_iff_existsUnique]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
hF' : IsSheafFor F (ofArrows X (Cofan.inj c))
this : HasCoproduct X
⊢ ∀ (b : ∏ fun b => F.obj ((fun x => op (X x)) b)), ∃! a, Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c) a = b

Next tactic:
rw [Equalizer.Presieve.Arrows.sheaf_condition, Limits.Types.type_equalizer_iff_unique] at hF'