l3lab/ntp-mathlib huggingface dataset:
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y : (j : J) × (forget C).obj (F.obj j)
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
hh : ∃ k f g, (F.map f) x.snd = (F.map g) y.snd
⊢ ∃ k f g, (F.map f) y.snd = (F.map g) x.snd

Next tactic:
case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    exact ⟨k, g, f, hh.symm⟩
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y : (j : J) × (forget C).obj (F.obj j)
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
hh : ∃ k f g, (F.map f) x.snd = (F.map g) y.snd
⊢ ∃ k f g, (F.map f) y.snd = (F.map g) x.snd

Next tactic:
obtain ⟨k, f, g, hh⟩ := hh
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    

Proof state:
case intro.intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y : (j : J) × (forget C).obj (F.obj j)
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
k : J
f : x.fst ⟶ k
g : y.fst ⟶ k
hh : (F.map f) x.snd = (F.map g) y.snd
⊢ ∃ k f g, (F.map f) y.snd = (F.map g) x.snd

Next tactic:
exact ⟨k, g, f, hh.symm⟩
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    exact ⟨k, g, f, hh.symm⟩
  

Proof state:
case trans
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x : (forget C).obj (F.obj i)
y : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x } { fst := j, snd := y }
a b x✝ y✝ z✝ : (j : J) × (forget C).obj (F.obj j)
a✝¹ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x✝ y✝
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) y✝ z✝
a_ih✝¹ : ∃ k f g, (F.map f) x✝.snd = (F.map g) y✝.snd
a_ih✝ : ∃ k f g, (F.map f) y✝.snd = (F.map g) z✝.snd
⊢ ∃ k f g, (F.map f) x✝.snd = (F.map g) z✝.snd

Next tactic:
case trans x y z _ _ hh1 hh2 =>
    obtain ⟨k1, f1, g1, h1⟩ := hh1
    obtain ⟨k2, f2, g2, h2⟩ := hh2
    let k0 : J := IsFiltered.max k1 k2
    let e1 : k1 ⟶ k0 := IsFiltered.leftToMax _ _
    let e2 : k2 ⟶ k0 := IsFiltered.rightToMax _ _
    let k : J := IsFiltered.coeq (g1 ≫ e1) (f2 ≫ e2)
    let e : k0 ⟶ k := IsFiltered.coeqHom _ _
    use k, f1 ≫ e1 ≫ e, g2 ≫ e2 ≫ e
    simp only [F.map_comp, comp_apply, h1, ← h2]
    simp only [← comp_apply, ← F.map_comp]
    rw [IsFiltered.coeq_condition]
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    exact ⟨k, g, f, hh.symm⟩
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y z : (j : J) × (forget C).obj (F.obj j)
a✝¹ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) y z
hh1 : ∃ k f g, (F.map f) x.snd = (F.map g) y.snd
hh2 : ∃ k f g, (F.map f) y.snd = (F.map g) z.snd
⊢ ∃ k f g, (F.map f) x.snd = (F.map g) z.snd

Next tactic:
case trans x y z _ _ hh1 hh2 =>
    obtain ⟨k1, f1, g1, h1⟩ := hh1
    obtain ⟨k2, f2, g2, h2⟩ := hh2
    let k0 : J := IsFiltered.max k1 k2
    let e1 : k1 ⟶ k0 := IsFiltered.leftToMax _ _
    let e2 : k2 ⟶ k0 := IsFiltered.rightToMax _ _
    let k : J := IsFiltered.coeq (g1 ≫ e1) (f2 ≫ e2)
    let e : k0 ⟶ k := IsFiltered.coeqHom _ _
    use k, f1 ≫ e1 ≫ e, g2 ≫ e2 ≫ e
    simp only [F.map_comp, comp_apply, h1, ← h2]
    simp only [← comp_apply, ← F.map_comp]
    rw [IsFiltered.coeq_condition]
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    exact ⟨k, g, f, hh.symm⟩
  case trans x y z _ _ hh1 hh2 =>
    

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y z : (j : J) × (forget C).obj (F.obj j)
a✝¹ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) y z
hh1 : ∃ k f g, (F.map f) x.snd = (F.map g) y.snd
hh2 : ∃ k f g, (F.map f) y.snd = (F.map g) z.snd
⊢ ∃ k f g, (F.map f) x.snd = (F.map g) z.snd

Next tactic:
obtain ⟨k1, f1, g1, h1⟩ := hh1
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    exact ⟨k, g, f, hh.symm⟩
  case trans x y z _ _ hh1 hh2 =>
    obtain ⟨k1, f1, g1, h1⟩ := hh1
    

Proof state:
case intro.intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y z : (j : J) × (forget C).obj (F.obj j)
a✝¹ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) y z
hh2 : ∃ k f g, (F.map f) y.snd = (F.map g) z.snd
k1 : J
f1 : x.fst ⟶ k1
g1 : y.fst ⟶ k1
h1 : (F.map f1) x.snd = (F.map g1) y.snd
⊢ ∃ k f g, (F.map f) x.snd = (F.map g) z.snd

Next tactic:
obtain ⟨k2, f2, g2, h2⟩ := hh2
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    exact ⟨k, g, f, hh.symm⟩
  case trans x y z _ _ hh1 hh2 =>
    obtain ⟨k1, f1, g1, h1⟩ := hh1
    obtain ⟨k2, f2, g2, h2⟩ := hh2
    

Proof state:
case intro.intro.intro.intro.intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y z : (j : J) × (forget C).obj (F.obj j)
a✝¹ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) y z
k1 : J
f1 : x.fst ⟶ k1
g1 : y.fst ⟶ k1
h1 : (F.map f1) x.snd = (F.map g1) y.snd
k2 : J
f2 : y.fst ⟶ k2
g2 : z.fst ⟶ k2
h2 : (F.map f2) y.snd = (F.map g2) z.snd
⊢ ∃ k f g, (F.map f) x.snd = (F.map g) z.snd

Next tactic:
let k0 : J := IsFiltered.max k1 k2
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    exact ⟨k, g, f, hh.symm⟩
  case trans x y z _ _ hh1 hh2 =>
    obtain ⟨k1, f1, g1, h1⟩ := hh1
    obtain ⟨k2, f2, g2, h2⟩ := hh2
    let k0 : J := IsFiltered.max k1 k2
    

Proof state:
case intro.intro.intro.intro.intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y z : (j : J) × (forget C).obj (F.obj j)
a✝¹ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) y z
k1 : J
f1 : x.fst ⟶ k1
g1 : y.fst ⟶ k1
h1 : (F.map f1) x.snd = (F.map g1) y.snd
k2 : J
f2 : y.fst ⟶ k2
g2 : z.fst ⟶ k2
h2 : (F.map f2) y.snd = (F.map g2) z.snd
k0 : J := IsFiltered.max k1 k2
⊢ ∃ k f g, (F.map f) x.snd = (F.map g) z.snd

Next tactic:
let e1 : k1 ⟶ k0 := IsFiltered.leftToMax _ _
theorem Concrete.isColimit_exists_of_rep_eq {D : Cocone F} {i j : J} (hD : IsColimit D)
    (x : F.obj i) (y : F.obj j) (h : D.ι.app _ x = D.ι.app _ y) :
    ∃ (k : _) (f : i ⟶ k) (g : j ⟶ k), F.map f x = F.map g y := by
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
  let T : E ≅ G := hE.uniqueUpToIso hG
  let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
  apply_fun TX.hom at h
  change (E.ι.app i ≫ TX.hom) x = (E.ι.app j ≫ TX.hom) y at h
  erw [T.hom.w, T.hom.w] at h
  replace h := Quot.exact _ h
  suffices
    ∀ (a b : Σj, F.obj j) (_ : EqvGen (Limits.Types.Quot.Rel.{v, v} (F ⋙ forget C)) a b),
      ∃ (k : _) (f : a.1 ⟶ k) (g : b.1 ⟶ k), F.map f a.2 = F.map g b.2
    by exact this ⟨i, x⟩ ⟨j, y⟩ h
  intro a b h
  induction h
  case rel x y hh =>
    obtain ⟨e, he⟩ := hh
    use y.1, e, 𝟙 _
    simpa using he.symm
  case refl x =>
    exact ⟨x.1, 𝟙 _, 𝟙 _, rfl⟩
  case symm x y _ hh =>
    obtain ⟨k, f, g, hh⟩ := hh
    exact ⟨k, g, f, hh.symm⟩
  case trans x y z _ _ hh1 hh2 =>
    obtain ⟨k1, f1, g1, h1⟩ := hh1
    obtain ⟨k2, f2, g2, h2⟩ := hh2
    let k0 : J := IsFiltered.max k1 k2
    let e1 : k1 ⟶ k0 := IsFiltered.leftToMax _ _
    

Proof state:
case intro.intro.intro.intro.intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
J : Type v
inst✝² : SmallCategory J
F : J ⥤ C
inst✝¹ : PreservesColimit F (forget C)
inst✝ : IsFiltered J
D : Cocone F
i j : J
hD : IsColimit D
x✝ : (forget C).obj (F.obj i)
y✝ : (forget C).obj (F.obj j)
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
G : Cocone (F ⋙ forget C) := Types.colimitCocone (F ⋙ forget C)
hG : IsColimit (Types.colimitCocone (F ⋙ forget C)) := Types.colimitCoconeIsColimit (F ⋙ forget C)
T : E ≅ G := IsColimit.uniqueUpToIso hE hG
TX : E.pt ≅ G.pt := (Cocones.forget (F ⋙ forget C)).mapIso T
h : EqvGen (Types.Quot.Rel (F ⋙ forget C)) { fst := i, snd := x✝ } { fst := j, snd := y✝ }
a b x y z : (j : J) × (forget C).obj (F.obj j)
a✝¹ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) x y
a✝ : EqvGen (Types.Quot.Rel (F ⋙ forget C)) y z
k1 : J
f1 : x.fst ⟶ k1
g1 : y.fst ⟶ k1
h1 : (F.map f1) x.snd = (F.map g1) y.snd
k2 : J
f2 : y.fst ⟶ k2
g2 : z.fst ⟶ k2
h2 : (F.map f2) y.snd = (F.map g2) z.snd
k0 : J := IsFiltered.max k1 k2
e1 : k1 ⟶ k0 := IsFiltered.leftToMax k1 k2
⊢ ∃ k f g, (F.map f) x.snd = (F.map g) z.snd

Next tactic:
let e2 : k2 ⟶ k0 := IsFiltered.rightToMax _ _