l3lab/ntp-mathlib huggingface dataset:
theorem isPullback_initial_to_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i j : Discrete ι) (hi : i ≠ j) :
    IsPullback (initial.to _) (initial.to _) (c.ι.app i) (c.ι.app j) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.350544, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.350551, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i j : Discrete ι
hi : i ≠ j
f : ι → C := F.obj ∘ Discrete.mk
this : F = Discrete.functor f
⊢ IsPullback (initial.to (F.obj i)) (initial.to (F.obj j)) (c.ι.app i) (c.ι.app j)

Next tactic:
clear_value f
theorem isPullback_initial_to_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i j : Discrete ι) (hi : i ≠ j) :
    IsPullback (initial.to _) (initial.to _) (c.ι.app i) (c.ι.app j) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.350544, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.350551, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i j : Discrete ι
hi : i ≠ j
f : ι → C
this : F = Discrete.functor f
⊢ IsPullback (initial.to (F.obj i)) (initial.to (F.obj j)) (c.ι.app i) (c.ι.app j)

Next tactic:
subst this
theorem isPullback_initial_to_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i j : Discrete ι) (hi : i ≠ j) :
    IsPullback (initial.to _) (initial.to _) (c.ι.app i) (c.ι.app j) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.350544, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.350551, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i j : Discrete ι
hi : i ≠ j
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ IsPullback (initial.to ((Discrete.functor f).obj i)) (initial.to ((Discrete.functor f).obj j)) (c.ι.app i) (c.ι.app j)

Next tactic:
convert isPullback_of_cofan_isVanKampen hc i.as j.as
theorem isPullback_initial_to_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i j : Discrete ι) (hi : i ≠ j) :
    IsPullback (initial.to _) (initial.to _) (c.ι.app i) (c.ι.app j) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  convert isPullback_of_cofan_isVanKampen hc i.as j.as
  

Proof state:
case h.e'_3
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.350544, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.350551, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i j : Discrete ι
hi : i ≠ j
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ (⊥_ C) = if j.as = i.as then f i.as else ⊥_ C

Next tactic:
exact (if_neg (mt (Discrete.ext _ _) hi.symm)).symm
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i : Discrete ι
⊢ Mono (c.ι.app i)

Next tactic:
classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
  nth_rw 1 [← Category.id_comp (c.ι.app i)]
  convert IsPullback.paste_vert _ (isPullback_of_cofan_isVanKampen hc i.as i.as)
  swap
  · exact (eqToHom (if_pos rfl).symm)
  · simp
  · exact IsPullback.of_vert_isIso ⟨by simp⟩
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i : Discrete ι
⊢ Mono (c.ι.app i)

Next tactic:
let f : ι → C := F.obj ∘ Discrete.mk
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i : Discrete ι
f : ι → C := F.obj ∘ Discrete.mk
⊢ Mono (c.ι.app i)

Next tactic:
have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by 

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i : Discrete ι
f : ι → C := F.obj ∘ Discrete.mk
⊢ ∀ (X Y : Discrete ι) (f_1 : X ⟶ Y), HEq (F.map f_1) ((Discrete.functor f).map f_1)

Next tactic:
rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; 

Proof state:
case mk.mk.up.up
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i✝ : Discrete ι
f : ι → C := F.obj ∘ Discrete.mk
i : ι
⊢ HEq (F.map { down := { down := (_ : i = i) } }) ((Discrete.functor f).map { down := { down := (_ : i = i) } })

Next tactic:
simp
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i : Discrete ι
f : ι → C := F.obj ∘ Discrete.mk
this : F = Discrete.functor f
⊢ Mono (c.ι.app i)

Next tactic:
clear_value f
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
F : Discrete ι ⥤ C
c : Cocone F
hc : IsVanKampenColimit c
i : Discrete ι
f : ι → C
this : F = Discrete.functor f
⊢ Mono (c.ι.app i)

Next tactic:
subst this
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ Mono (c.ι.app i)

Next tactic:
refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ IsPullback (𝟙 ((Discrete.functor f).obj i)) (𝟙 ((Discrete.functor f).obj i)) (c.ι.app i) (c.ι.app i)

Next tactic:
nth_rw 1 [← Category.id_comp (c.ι.app i)]
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
  nth_rw 1 [← Category.id_comp (c.ι.app i)]
  

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ IsPullback (𝟙 ((Discrete.functor f).obj i)) (𝟙 ((Discrete.functor f).obj i))
    (𝟙 ((Discrete.functor f).obj i) ≫ c.ι.app i) (c.ι.app i)

Next tactic:
convert IsPullback.paste_vert _ (isPullback_of_cofan_isVanKampen hc i.as i.as)
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
  nth_rw 1 [← Category.id_comp (c.ι.app i)]
  convert IsPullback.paste_vert _ (isPullback_of_cofan_isVanKampen hc i.as i.as)
  

Proof state:
case h.e'_8.h
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
e_5✝ : (Discrete.functor f).obj i = f i.as
⊢ 𝟙 ((Discrete.functor f).obj i) =
    ?convert_4 ≫
      if h : i.as = i.as then eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = f i.as)
      else eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = ⊥_ C) ≫ initial.to (f i.as)
case convert_4
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ (Discrete.functor f).obj i ⟶ if i.as = i.as then f i.as else ⊥_ C
case convert_6
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ IsPullback (𝟙 ((Discrete.functor f).obj i)) ?convert_4 (𝟙 ((Discrete.functor f).obj i))
    (if h : i.as = i.as then eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = f i.as)
    else eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = ⊥_ C) ≫ initial.to (f i.as))

Next tactic:
swap
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
  nth_rw 1 [← Category.id_comp (c.ι.app i)]
  convert IsPullback.paste_vert _ (isPullback_of_cofan_isVanKampen hc i.as i.as)
  swap
  · 

Proof state:
case convert_4
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ (Discrete.functor f).obj i ⟶ if i.as = i.as then f i.as else ⊥_ C

Next tactic:
exact (eqToHom (if_pos rfl).symm)
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
  nth_rw 1 [← Category.id_comp (c.ι.app i)]
  convert IsPullback.paste_vert _ (isPullback_of_cofan_isVanKampen hc i.as i.as)
  swap
  · exact (eqToHom (if_pos rfl).symm)
  · 

Proof state:
case h.e'_8.h
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
e_5✝ : (Discrete.functor f).obj i = f i.as
⊢ 𝟙 ((Discrete.functor f).obj i) =
    eqToHom (_ : (Discrete.functor f).obj i = if i.as = i.as then (Discrete.functor f).obj i else ⊥_ C) ≫
      if h : i.as = i.as then eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = f i.as)
      else eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = ⊥_ C) ≫ initial.to (f i.as)

Next tactic:
simp
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
  nth_rw 1 [← Category.id_comp (c.ι.app i)]
  convert IsPullback.paste_vert _ (isPullback_of_cofan_isVanKampen hc i.as i.as)
  swap
  · exact (eqToHom (if_pos rfl).symm)
  · simp
  · 

Proof state:
case convert_6
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ IsPullback (𝟙 ((Discrete.functor f).obj i))
    (eqToHom (_ : (Discrete.functor f).obj i = if i.as = i.as then (Discrete.functor f).obj i else ⊥_ C))
    (𝟙 ((Discrete.functor f).obj i))
    (if h : i.as = i.as then eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = f i.as)
    else eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = ⊥_ C) ≫ initial.to (f i.as))

Next tactic:
exact IsPullback.of_vert_isIso ⟨by simp⟩
theorem mono_of_cofan_isVanKampen [HasInitial C] {ι : Type*} {F : Discrete ι ⥤ C}
    {c : Cocone F} (hc : IsVanKampenColimit c) (i : Discrete ι) : Mono (c.ι.app i) := by
  classical
  let f : ι → C := F.obj ∘ Discrete.mk
  have : F = Discrete.functor f :=
    Functor.hext (fun i ↦ rfl) (by rintro ⟨i⟩ ⟨j⟩ ⟨⟨rfl : i = j⟩⟩; simp)
  clear_value f
  subst this
  refine' PullbackCone.mono_of_isLimitMkIdId _ (IsPullback.isLimit _)
  nth_rw 1 [← Category.id_comp (c.ι.app i)]
  convert IsPullback.paste_vert _ (isPullback_of_cofan_isVanKampen hc i.as i.as)
  swap
  · exact (eqToHom (if_pos rfl).symm)
  · simp
  · exact IsPullback.of_vert_isIso ⟨by 

Proof state:
J : Type v'
inst✝⁴ : Category.{u', v'} J
C : Type u
inst✝³ : Category.{v, u} C
K : Type u_1
inst✝² : Category.{?u.370808, u_1} K
D : Type u_2
inst✝¹ : Category.{?u.370815, u_2} D
inst✝ : HasInitial C
ι : Type u_3
i : Discrete ι
f : ι → C
c : Cocone (Discrete.functor f)
hc : IsVanKampenColimit c
⊢ 𝟙 ((Discrete.functor f).obj i) ≫ 𝟙 ((Discrete.functor f).obj i) =
    eqToHom (_ : (Discrete.functor f).obj i = if i.as = i.as then (Discrete.functor f).obj i else ⊥_ C) ≫
      if h : i.as = i.as then eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = f i.as)
      else eqToHom (_ : (if i.as = i.as then f i.as else ⊥_ C) = ⊥_ C) ≫ initial.to (f i.as)

Next tactic:
simp
@[to_additive addIndex_empty]
theorem index_empty {V : Set G} : index ∅ V = 0 := by
  

Proof state:
G : Type u_1
inst✝ : Group G
V : Set G
⊢ index ∅ V = 0

Next tactic:
simp only [index, Nat.sInf_eq_zero]
@[to_additive addIndex_empty]
theorem index_empty {V : Set G} : index ∅ V = 0 := by
  simp only [index, Nat.sInf_eq_zero]; 

Proof state:
G : Type u_1
inst✝ : Group G
V : Set G
⊢ 0 ∈ Finset.card '' {t | ∅ ⊆ ⋃ g ∈ t, (fun h => g * h) ⁻¹' V} ∨
    Finset.card '' {t | ∅ ⊆ ⋃ g ∈ t, (fun h => g * h) ⁻¹' V} = ∅

Next tactic:
left
@[to_additive addIndex_empty]
theorem index_empty {V : Set G} : index ∅ V = 0 := by
  simp only [index, Nat.sInf_eq_zero]; left; 

Proof state:
case h
G : Type u_1
inst✝ : Group G
V : Set G
⊢ 0 ∈ Finset.card '' {t | ∅ ⊆ ⋃ g ∈ t, (fun h => g * h) ⁻¹' V}

Next tactic:
use ∅
@[to_additive addIndex_empty]
theorem index_empty {V : Set G} : index ∅ V = 0 := by
  simp only [index, Nat.sInf_eq_zero]; left; use ∅
  

Proof state:
case h
G : Type u_1
inst✝ : Group G
V : Set G
⊢ ∅ ∈ {t | ∅ ⊆ ⋃ g ∈ t, (fun h => g * h) ⁻¹' V} ∧ Finset.card ∅ = 0

Next tactic:
simp only [Finset.card_empty, empty_subset, mem_setOf_eq, eq_self_iff_true, and_self_iff]
@[to_additive]
theorem prehaar_empty (K₀ : PositiveCompacts G) {U : Set G} : prehaar (K₀ : Set G) U ⊥ = 0 := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
inst✝ : TopologicalSpace G
K₀ : PositiveCompacts G
U : Set G
⊢ prehaar (↑K₀) U ⊥ = 0

Next tactic:
rw [prehaar, Compacts.coe_bot, index_empty, Nat.cast_zero, zero_div]
@[to_additive]
theorem prehaar_nonneg (K₀ : PositiveCompacts G) {U : Set G} (K : Compacts G) :
    0 ≤ prehaar (K₀ : Set G) U K := by 

Proof state:
G : Type u_1
inst✝¹ : Group G
inst✝ : TopologicalSpace G
K₀ : PositiveCompacts G
U : Set G
K : Compacts G
⊢ 0 ≤ prehaar (↑K₀) U K

Next tactic:
apply div_nonneg
@[to_additive]
theorem prehaar_nonneg (K₀ : PositiveCompacts G) {U : Set G} (K : Compacts G) :
    0 ≤ prehaar (K₀ : Set G) U K := by apply div_nonneg <;> 

Proof state:
case ha
G : Type u_1
inst✝¹ : Group G
inst✝ : TopologicalSpace G
K₀ : PositiveCompacts G
U : Set G
K : Compacts G
⊢ 0 ≤ ↑(index (↑K) U)

Next tactic:
norm_cast
@[to_additive]
theorem prehaar_nonneg (K₀ : PositiveCompacts G) {U : Set G} (K : Compacts G) :
    0 ≤ prehaar (K₀ : Set G) U K := by apply div_nonneg <;> 

Proof state:
case hb
G : Type u_1
inst✝¹ : Group G
inst✝ : TopologicalSpace G
K₀ : PositiveCompacts G
U : Set G
K : Compacts G
⊢ 0 ≤ ↑(index (↑K₀) U)

Next tactic:
norm_cast
@[to_additive]
theorem prehaar_nonneg (K₀ : PositiveCompacts G) {U : Set G} (K : Compacts G) :
    0 ≤ prehaar (K₀ : Set G) U K := by apply div_nonneg <;> norm_cast <;> 

Proof state:
case ha
G : Type u_1
inst✝¹ : Group G
inst✝ : TopologicalSpace G
K₀ : PositiveCompacts G
U : Set G
K : Compacts G
⊢ 0 ≤ index (↑K) U

Next tactic:
apply zero_le
@[to_additive]
theorem prehaar_nonneg (K₀ : PositiveCompacts G) {U : Set G} (K : Compacts G) :
    0 ≤ prehaar (K₀ : Set G) U K := by apply div_nonneg <;> norm_cast <;> 

Proof state:
case hb
G : Type u_1
inst✝¹ : Group G
inst✝ : TopologicalSpace G
K₀ : PositiveCompacts G
U : Set G
K : Compacts G
⊢ 0 ≤ index (↑K₀) U

Next tactic:
apply zero_le
@[to_additive (attr := simp)]
theorem mem_prehaar_empty {K₀ : Set G} {f : Compacts G → ℝ} :
    f ∈ haarProduct K₀ ↔ ∀ K : Compacts G, f K ∈ Icc (0 : ℝ) (index (K : Set G) K₀) := by
  

Proof state:
G : Type u_1
inst✝¹ : Group G
inst✝ : TopologicalSpace G
K₀ : Set G
f : Compacts G → ℝ
⊢ f ∈ haarProduct K₀ ↔ ∀ (K : Compacts G), f K ∈ Icc 0 ↑(index (↑K) K₀)

Next tactic:
simp only [haarProduct, Set.pi, forall_prop_of_true, mem_univ, mem_setOf_eq]
/-- If `K` is compact and `V` has nonempty interior, then the index `(K : V)` is well-defined,
  there is a finite set `t` satisfying the desired properties. -/
@[to_additive addIndex_defined
"If `K` is compact and `V` has nonempty interior, then the index `(K : V)` is well-defined, there is
a finite set `t` satisfying the desired properties."]
theorem index_defined {K V : Set G} (hK : IsCompact K) (hV : (interior V).Nonempty) :
    ∃ n : ℕ, n ∈ Finset.card '' { t : Finset G | K ⊆ ⋃ g ∈ t, (fun h => g * h) ⁻¹' V } := by
  

Proof state:
G : Type u_1
inst✝² : Group G
inst✝¹ : TopologicalSpace G
inst✝ : TopologicalGroup G
K V : Set G
hK : IsCompact K
hV : Set.Nonempty (interior V)
⊢ ∃ n, n ∈ Finset.card '' {t | K ⊆ ⋃ g ∈ t, (fun h => g * h) ⁻¹' V}

Next tactic:
rcases compact_covered_by_mul_left_translates hK hV with ⟨t, ht⟩
/-- If `K` is compact and `V` has nonempty interior, then the index `(K : V)` is well-defined,
  there is a finite set `t` satisfying the desired properties. -/
@[to_additive addIndex_defined
"If `K` is compact and `V` has nonempty interior, then the index `(K : V)` is well-defined, there is
a finite set `t` satisfying the desired properties."]
theorem index_defined {K V : Set G} (hK : IsCompact K) (hV : (interior V).Nonempty) :
    ∃ n : ℕ, n ∈ Finset.card '' { t : Finset G | K ⊆ ⋃ g ∈ t, (fun h => g * h) ⁻¹' V } := by
  rcases compact_covered_by_mul_left_translates hK hV with ⟨t, ht⟩; 

Proof state:
case intro
G : Type u_1
inst✝² : Group G
inst✝¹ : TopologicalSpace G
inst✝ : TopologicalGroup G
K V : Set G
hK : IsCompact K
hV : Set.Nonempty (interior V)
t : Finset G
ht : K ⊆ ⋃ g ∈ t, (fun x => g * x) ⁻¹' V
⊢ ∃ n, n ∈ Finset.card '' {t | K ⊆ ⋃ g ∈ t, (fun h => g * h) ⁻¹' V}

Next tactic:
exact ⟨t.card, t, ht, rfl⟩