l3lab/ntp-mathlib huggingface dataset:
/-- If `μ` is a regular content, then the measure induced by `μ` will agree with `μ`
  on compact sets. -/
theorem measure_eq_content_of_regular (H : MeasureTheory.Content.ContentRegular μ)
    (K : TopologicalSpace.Compacts G) : μ.measure ↑K = μ K := by
  refine' le_antisymm _ _
  · apply ENNReal.le_of_forall_pos_le_add
    intro ε εpos _
    obtain ⟨K', K'_hyp⟩ := contentRegular_exists_compact μ H K (ne_bot_of_gt εpos)
    calc
      μ.measure ↑K ≤ μ.measure (interior ↑K') := by
        rw [μ.measure_apply isOpen_interior.measurableSet,
          μ.measure_apply K.isCompact.measurableSet]
        exact μ.outerMeasure.mono K'_hyp.left
      _ ≤ μ K' := by
        

Proof state:
G : Type w
inst✝³ : TopologicalSpace G
μ : Content G
inst✝² : MeasurableSpace G
inst✝¹ : T2Space G
inst✝ : BorelSpace G
H : ContentRegular μ
K : Compacts G
ε : ℝ≥0
εpos : 0 < ε
a✝ : (fun s => ↑(toFun μ s)) K < ⊤
K' : Compacts G
K'_hyp : K.carrier ⊆ interior K'.carrier ∧ (fun s => ↑(toFun μ s)) K' ≤ (fun s => ↑(toFun μ s)) K + ↑ε
⊢ ↑↑(Content.measure μ) (interior ↑K') ≤ (fun s => ↑(toFun μ s)) K'

Next tactic:
rw [μ.measure_apply (IsOpen.measurableSet isOpen_interior)]
/-- If `μ` is a regular content, then the measure induced by `μ` will agree with `μ`
  on compact sets. -/
theorem measure_eq_content_of_regular (H : MeasureTheory.Content.ContentRegular μ)
    (K : TopologicalSpace.Compacts G) : μ.measure ↑K = μ K := by
  refine' le_antisymm _ _
  · apply ENNReal.le_of_forall_pos_le_add
    intro ε εpos _
    obtain ⟨K', K'_hyp⟩ := contentRegular_exists_compact μ H K (ne_bot_of_gt εpos)
    calc
      μ.measure ↑K ≤ μ.measure (interior ↑K') := by
        rw [μ.measure_apply isOpen_interior.measurableSet,
          μ.measure_apply K.isCompact.measurableSet]
        exact μ.outerMeasure.mono K'_hyp.left
      _ ≤ μ K' := by
        rw [μ.measure_apply (IsOpen.measurableSet isOpen_interior)]
        

Proof state:
G : Type w
inst✝³ : TopologicalSpace G
μ : Content G
inst✝² : MeasurableSpace G
inst✝¹ : T2Space G
inst✝ : BorelSpace G
H : ContentRegular μ
K : Compacts G
ε : ℝ≥0
εpos : 0 < ε
a✝ : (fun s => ↑(toFun μ s)) K < ⊤
K' : Compacts G
K'_hyp : K.carrier ⊆ interior K'.carrier ∧ (fun s => ↑(toFun μ s)) K' ≤ (fun s => ↑(toFun μ s)) K + ↑ε
⊢ ↑(Content.outerMeasure μ) (interior ↑K') ≤ (fun s => ↑(toFun μ s)) K'

Next tactic:
exact μ.outerMeasure_interior_compacts K'
/-- If `μ` is a regular content, then the measure induced by `μ` will agree with `μ`
  on compact sets. -/
theorem measure_eq_content_of_regular (H : MeasureTheory.Content.ContentRegular μ)
    (K : TopologicalSpace.Compacts G) : μ.measure ↑K = μ K := by
  refine' le_antisymm _ _
  · apply ENNReal.le_of_forall_pos_le_add
    intro ε εpos _
    obtain ⟨K', K'_hyp⟩ := contentRegular_exists_compact μ H K (ne_bot_of_gt εpos)
    calc
      μ.measure ↑K ≤ μ.measure (interior ↑K') := by
        rw [μ.measure_apply isOpen_interior.measurableSet,
          μ.measure_apply K.isCompact.measurableSet]
        exact μ.outerMeasure.mono K'_hyp.left
      _ ≤ μ K' := by
        rw [μ.measure_apply (IsOpen.measurableSet isOpen_interior)]
        exact μ.outerMeasure_interior_compacts K'
      _ ≤ μ K + ε := K'_hyp.right
  · 

Proof state:
case refine'_2
G : Type w
inst✝³ : TopologicalSpace G
μ : Content G
inst✝² : MeasurableSpace G
inst✝¹ : T2Space G
inst✝ : BorelSpace G
H : ContentRegular μ
K : Compacts G
⊢ (fun s => ↑(toFun μ s)) K ≤ ↑↑(Content.measure μ) ↑K

Next tactic:
rw [μ.measure_apply (IsCompact.measurableSet K.isCompact)]
/-- If `μ` is a regular content, then the measure induced by `μ` will agree with `μ`
  on compact sets. -/
theorem measure_eq_content_of_regular (H : MeasureTheory.Content.ContentRegular μ)
    (K : TopologicalSpace.Compacts G) : μ.measure ↑K = μ K := by
  refine' le_antisymm _ _
  · apply ENNReal.le_of_forall_pos_le_add
    intro ε εpos _
    obtain ⟨K', K'_hyp⟩ := contentRegular_exists_compact μ H K (ne_bot_of_gt εpos)
    calc
      μ.measure ↑K ≤ μ.measure (interior ↑K') := by
        rw [μ.measure_apply isOpen_interior.measurableSet,
          μ.measure_apply K.isCompact.measurableSet]
        exact μ.outerMeasure.mono K'_hyp.left
      _ ≤ μ K' := by
        rw [μ.measure_apply (IsOpen.measurableSet isOpen_interior)]
        exact μ.outerMeasure_interior_compacts K'
      _ ≤ μ K + ε := K'_hyp.right
  · rw [μ.measure_apply (IsCompact.measurableSet K.isCompact)]
    

Proof state:
case refine'_2
G : Type w
inst✝³ : TopologicalSpace G
μ : Content G
inst✝² : MeasurableSpace G
inst✝¹ : T2Space G
inst✝ : BorelSpace G
H : ContentRegular μ
K : Compacts G
⊢ (fun s => ↑(toFun μ s)) K ≤ ↑(Content.outerMeasure μ) ↑K

Next tactic:
exact μ.le_outerMeasure_compacts K
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
⊢ Function.Injective fun x j => (D.π.app j) x

Next tactic:
let E := (forget C).mapCone D
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
⊢ Function.Injective fun x j => (D.π.app j) x

Next tactic:
let hE : IsLimit E := isLimitOfPreserves _ hD
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
⊢ Function.Injective fun x j => (D.π.app j) x

Next tactic:
let G := Types.limitCone.{w, v} (F ⋙ forget C)
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
⊢ Function.Injective fun x j => (D.π.app j) x

Next tactic:
let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
⊢ Function.Injective fun x j => (D.π.app j) x

Next tactic:
let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
⊢ Function.Injective fun x j => (D.π.app j) x

Next tactic:
change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
⊢ Function.Injective (T.hom ≫ fun x j => G.π.app j x)

Next tactic:
have h : Function.Injective T.hom := by
    intro a b h
    suffices T.inv (T.hom a) = T.inv (T.hom b) by simpa
    rw [h]
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
  have h : Function.Injective T.hom := by
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
⊢ Function.Injective T.hom

Next tactic:
intro a b h
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
  have h : Function.Injective T.hom := by
    intro a b h
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
a b : E.pt
h : T.hom a = T.hom b
⊢ a = b

Next tactic:
suffices T.inv (T.hom a) = T.inv (T.hom b) by simpa
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
  have h : Function.Injective T.hom := by
    intro a b h
    suffices T.inv (T.hom a) = T.inv (T.hom b) by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
a b : E.pt
h : T.hom a = T.hom b
this : T.inv (T.hom a) = T.inv (T.hom b)
⊢ a = b

Next tactic:
simpa
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
  have h : Function.Injective T.hom := by
    intro a b h
    suffices T.inv (T.hom a) = T.inv (T.hom b) by simpa
    

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
a b : E.pt
h : T.hom a = T.hom b
⊢ T.inv (T.hom a) = T.inv (T.hom b)

Next tactic:
rw [h]
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
  have h : Function.Injective T.hom := by
    intro a b h
    suffices T.inv (T.hom a) = T.inv (T.hom b) by simpa
    rw [h]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
h : Function.Injective T.hom
⊢ Function.Injective (T.hom ≫ fun x j => G.π.app j x)

Next tactic:
suffices Function.Injective fun (x : G.pt) j => G.π.app j x by exact this.comp h
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
  have h : Function.Injective T.hom := by
    intro a b h
    suffices T.inv (T.hom a) = T.inv (T.hom b) by simpa
    rw [h]
  suffices Function.Injective fun (x : G.pt) j => G.π.app j x by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
h : Function.Injective T.hom
this : Function.Injective fun x j => G.π.app j x
⊢ Function.Injective (T.hom ≫ fun x j => G.π.app j x)

Next tactic:
exact this.comp h
theorem Concrete.to_product_injective_of_isLimit {D : Cone F} (hD : IsLimit D) :
    Function.Injective fun (x : D.pt) (j : J) => D.π.app j x := by
  let E := (forget C).mapCone D
  let hE : IsLimit E := isLimitOfPreserves _ hD
  let G := Types.limitCone.{w, v} (F ⋙ forget C)
  let hG := Types.limitConeIsLimit.{w, v} (F ⋙ forget C)
  let T : E.pt ≅ G.pt := hE.conePointUniqueUpToIso hG
  change Function.Injective (T.hom ≫ fun x j => G.π.app j x)
  have h : Function.Injective T.hom := by
    intro a b h
    suffices T.inv (T.hom a) = T.inv (T.hom b) by simpa
    rw [h]
  suffices Function.Injective fun (x : G.pt) j => G.π.app j x by exact this.comp h
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : ConcreteCategory C
J : Type w
inst✝¹ : SmallCategory J
F : J ⥤ C
inst✝ : PreservesLimit F (forget C)
D : Cone F
hD : IsLimit D
E : Cone (F ⋙ forget C) := (forget C).mapCone D
hE : IsLimit E := isLimitOfPreserves (forget C) hD
G : Cone (F ⋙ forget C) := Types.limitCone (F ⋙ forget C)
hG : IsLimit (Types.limitCone (F ⋙ forget C)) := Types.limitConeIsLimit (F ⋙ forget C)
T : E.pt ≅ G.pt := IsLimit.conePointUniqueUpToIso hE hG
h : Function.Injective T.hom
⊢ Function.Injective fun x j => G.π.app j x

Next tactic:
apply Subtype.ext
theorem Concrete.from_union_surjective_of_isColimit {D : Cocone F} (hD : IsColimit D) :
    let ff : (Σj : J, F.obj j) → D.pt := fun a => D.ι.app a.1 a.2
    Function.Surjective ff := by
  

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)
D : Cocone F
hD : IsColimit D
⊢ let ff := fun a => (D.ι.app a.fst) a.snd;
  Function.Surjective ff

Next tactic:
intro ff
theorem Concrete.from_union_surjective_of_isColimit {D : Cocone F} (hD : IsColimit D) :
    let ff : (Σj : J, F.obj j) → D.pt := fun a => D.ι.app a.1 a.2
    Function.Surjective ff := by
  intro ff
  

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)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (D.ι.app a.fst) a.snd
⊢ Function.Surjective ff

Next tactic:
let E := (forget C).mapCocone D
theorem Concrete.from_union_surjective_of_isColimit {D : Cocone F} (hD : IsColimit D) :
    let ff : (Σj : J, F.obj j) → D.pt := fun a => D.ι.app a.1 a.2
    Function.Surjective ff := by
  intro ff
  let E := (forget C).mapCocone D
  

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)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (D.ι.app a.fst) a.snd
E : Cocone (F ⋙ forget C) := (forget C).mapCocone D
⊢ Function.Surjective ff

Next tactic:
let hE : IsColimit E := isColimitOfPreserves _ hD
theorem Concrete.from_union_surjective_of_isColimit {D : Cocone F} (hD : IsColimit D) :
    let ff : (Σj : J, F.obj j) → D.pt := fun a => D.ι.app a.1 a.2
    Function.Surjective ff := by
  intro ff
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  

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)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (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

Next tactic:
let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
theorem Concrete.from_union_surjective_of_isColimit {D : Cocone F} (hD : IsColimit D) :
    let ff : (Σj : J, F.obj j) → D.pt := fun a => D.ι.app a.1 a.2
    Function.Surjective ff := by
  intro ff
  let E := (forget C).mapCocone D
  let hE : IsColimit E := isColimitOfPreserves _ hD
  let G := Types.colimitCocone.{v, v} (F ⋙ forget C)
  

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)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (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

Next tactic:
let hG := Types.colimitCoconeIsColimit.{v, v} (F ⋙ forget C)
theorem Concrete.from_union_surjective_of_isColimit {D : Cocone F} (hD : IsColimit D) :
    let ff : (Σj : J, F.obj j) → D.pt := fun a => D.ι.app a.1 a.2
    Function.Surjective ff := by
  intro ff
  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)
  

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)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (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

Next tactic:
let T : E ≅ G := hE.uniqueUpToIso hG
theorem Concrete.from_union_surjective_of_isColimit {D : Cocone F} (hD : IsColimit D) :
    let ff : (Σj : J, F.obj j) → D.pt := fun a => D.ι.app a.1 a.2
    Function.Surjective ff := by
  intro ff
  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
  

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)
D : Cocone F
hD : IsColimit D
ff : (j : J) × (forget C).obj (F.obj j) → (forget C).obj D.pt := fun a => (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

Next tactic:
let TX : E.pt ≅ G.pt := (Cocones.forget _).mapIso T