Theorem: CategoryTheory.Limits.Concrete.from_union_surjective_of_isColimit
File: Mathlib/CategoryTheory/Limits/ConcreteCategory.lean

tactic: intro ff
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
⊢ let ff := fun a => (forget C).map (D.ι.app a.fst) a.snd;
  Function.Surjective ff

tactic: let E := (forget C).mapCocone D
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
⊢ Function.Surjective ff

tactic: let hE : IsColimit E := isColimitOfPreserves _ hD
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
⊢ Function.Surjective ff

tactic: let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
hE : IsColimit E := isColimitOfPreserves (forget C) hD
⊢ Function.Surjective ff

tactic: let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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)
⊢ Function.Surjective ff

tactic: let T : E ≅ G := hE.uniqueUpToIso hG
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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)
⊢ Function.Surjective ff

tactic: let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
⊢ Function.Surjective ff

tactic: suffices Function.Surjective (TX.hom ∘ ff) by
  intro a
  obtain ⟨b, hb⟩ := this (TX.hom a)
  refine' ⟨b, _⟩
  replace hb := congr_arg TX.inv hb
  change (TX.hom ≫ TX.inv) (ff b) = (TX.hom ≫ TX.inv) _ at hb
  simpa only [TX.hom_inv_id] using hb
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
⊢ Function.Surjective ff

tactic: have : TX.hom ∘ ff = fun a => G.ι.app a.1 a.2 := by
  ext a
  change (E.ι.app a.1 ≫ hE.desc G) a.2 = _
  rw [hE.fac]
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
⊢ Function.Surjective (TX.hom ∘ ff)

tactic: rw [this]
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : TX.hom ∘ ff = fun a => G.ι.app a.fst a.snd
⊢ Function.Surjective (TX.hom ∘ ff)

tactic: rintro ⟨⟨j, a⟩⟩
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : TX.hom ∘ ff = fun a => G.ι.app a.fst a.snd
⊢ Function.Surjective fun a => G.ι.app a.fst a.snd

tactic: exact ⟨⟨j, a⟩, rfl⟩
state_before: case mk.mk
C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : TX.hom ∘ ff = fun a => G.ι.app a.fst a.snd
b✝ : G.pt
j : J
a : (F ⋙ forget C).obj j
⊢ ∃ a_1, (fun a => G.ι.app a.fst a.snd) a_1 = Quot.mk (Types.Quot.Rel (F ⋙ forget C)) { fst := j, snd := a }

tactic: intro a
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : Function.Surjective (TX.hom ∘ ff)
⊢ Function.Surjective ff

tactic: obtain ⟨b, hb⟩ := this (TX.hom a)
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : Function.Surjective (TX.hom ∘ ff)
a : (forget C).obj D.pt
⊢ ∃ a_1, ff a_1 = a

tactic: refine' ⟨b, _⟩
state_before: case intro
C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : Function.Surjective (TX.hom ∘ ff)
a : (forget C).obj D.pt
b : (j : J) × (forget C).obj (F.obj j)
hb : (TX.hom ∘ ff) b = TX.hom a
⊢ ∃ a_1, ff a_1 = a

tactic: replace hb := congr_arg TX.inv hb
state_before: case intro
C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : Function.Surjective (TX.hom ∘ ff)
a : (forget C).obj D.pt
b : (j : J) × (forget C).obj (F.obj j)
hb : (TX.hom ∘ ff) b = TX.hom a
⊢ ff b = a

tactic: change (TX.hom ≫ TX.inv) (ff b) = (TX.hom ≫ TX.inv) _ at hb
state_before: case intro
C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : Function.Surjective (TX.hom ∘ ff)
a : (forget C).obj D.pt
b : (j : J) × (forget C).obj (F.obj j)
hb : TX.inv ((TX.hom ∘ ff) b) = TX.inv (TX.hom a)
⊢ ff b = a

tactic: simpa only [TX.hom_inv_id] using hb
state_before: case intro
C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
this : Function.Surjective (TX.hom ∘ ff)
a : (forget C).obj D.pt
b : (j : J) × (forget C).obj (F.obj j)
hb : (TX.hom ≫ TX.inv) (ff b) = (TX.hom ≫ TX.inv) a
⊢ ff b = a

tactic: ext a
state_before: C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
⊢ TX.hom ∘ ff = fun a => G.ι.app a.fst a.snd

tactic: change (E.ι.app a.1 ≫ hE.desc G) a.2 = _
state_before: case h
C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
a : (j : J) × (forget C).obj (F.obj j)
⊢ (TX.hom ∘ ff) a = G.ι.app a.fst a.snd

tactic: rw [hE.fac]
state_before: case h
C : Type u
inst✝³ : Category C
inst✝² : ConcreteCategory C
J : Type v
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesColimit F (forget C)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (forget C).map (D.ι.app a.fst) a.snd
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
a : (j : J) × (forget C).obj (F.obj j)
⊢ (E.ι.app a.fst ≫ IsColimit.desc hE G) a.snd = G.ι.app a.fst a.snd