l3lab/ntp-mathlib huggingface dataset:
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · 

Proof state:
case property.refine'_1
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
⊢ (ContinuousMap.mk fun x =>
        { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
          property :=
            (_ :
              f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) }) ≫
      PullbackCone.fst (pullbackCone f g) =
    PullbackCone.fst S

Next tactic:
delta pullbackCone
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        

Proof state:
case property.refine'_1
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
⊢ (ContinuousMap.mk fun x =>
        { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
          property :=
            (_ :
              f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) }) ≫
      PullbackCone.fst
        (PullbackCone.mk (pullbackFst f g) (pullbackSnd f g) (_ : pullbackFst f g ≫ f = pullbackSnd f g ≫ g)) =
    PullbackCone.fst S

Next tactic:
ext a
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        

Proof state:
case property.refine'_1.w
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
a : (forget TopCat).obj S.pt
⊢ ((ContinuousMap.mk fun x =>
          { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
            property :=
              (_ :
                f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                  g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) }) ≫
        PullbackCone.fst
          (PullbackCone.mk (pullbackFst f g) (pullbackSnd f g) (_ : pullbackFst f g ≫ f = pullbackSnd f g ≫ g)))
      a =
    (PullbackCone.fst S) a

Next tactic:
erw [comp_apply, ContinuousMap.coe_mk]
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · 

Proof state:
case property.refine'_2
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
⊢ (ContinuousMap.mk fun x =>
        { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
          property :=
            (_ :
              f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) }) ≫
      PullbackCone.snd (pullbackCone f g) =
    PullbackCone.snd S

Next tactic:
delta pullbackCone
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        

Proof state:
case property.refine'_2
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
⊢ (ContinuousMap.mk fun x =>
        { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
          property :=
            (_ :
              f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) }) ≫
      PullbackCone.snd
        (PullbackCone.mk (pullbackFst f g) (pullbackSnd f g) (_ : pullbackFst f g ≫ f = pullbackSnd f g ≫ g)) =
    PullbackCone.snd S

Next tactic:
ext a
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        

Proof state:
case property.refine'_2.w
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
a : (forget TopCat).obj S.pt
⊢ ((ContinuousMap.mk fun x =>
          { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
            property :=
              (_ :
                f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                  g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) }) ≫
        PullbackCone.snd
          (PullbackCone.mk (pullbackFst f g) (pullbackSnd f g) (_ : pullbackFst f g ≫ f = pullbackSnd f g ≫ g)))
      a =
    (PullbackCone.snd S) a

Next tactic:
erw [comp_apply, ContinuousMap.coe_mk]
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · 

Proof state:
case property.refine'_3
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
⊢ ∀ {m : S.pt ⟶ (pullbackCone f g).pt},
    m ≫ PullbackCone.fst (pullbackCone f g) = PullbackCone.fst S →
      m ≫ PullbackCone.snd (pullbackCone f g) = PullbackCone.snd S →
        m =
          ContinuousMap.mk fun x =>
            { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
              property :=
                (_ :
                  f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                    g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) }

Next tactic:
intro m h₁ h₂
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · intro m h₁ h₂
        -- Porting note: used to be ext x
        

Proof state:
case property.refine'_3
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
m : S.pt ⟶ (pullbackCone f g).pt
h₁ : m ≫ PullbackCone.fst (pullbackCone f g) = PullbackCone.fst S
h₂ : m ≫ PullbackCone.snd (pullbackCone f g) = PullbackCone.snd S
⊢ m =
    ContinuousMap.mk fun x =>
      { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
        property :=
          (_ :
            f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
              g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) }

Next tactic:
apply ContinuousMap.ext
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · intro m h₁ h₂
        -- Porting note: used to be ext x
        apply ContinuousMap.ext; 

Proof state:
case property.refine'_3.h
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
m : S.pt ⟶ (pullbackCone f g).pt
h₁ : m ≫ PullbackCone.fst (pullbackCone f g) = PullbackCone.fst S
h₂ : m ≫ PullbackCone.snd (pullbackCone f g) = PullbackCone.snd S
⊢ ∀ (a : ↑S.pt),
    m a =
      (ContinuousMap.mk fun x =>
          { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
            property :=
              (_ :
                f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                  g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) })
        a

Next tactic:
intro x
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · intro m h₁ h₂
        -- Porting note: used to be ext x
        apply ContinuousMap.ext; intro x
        

Proof state:
case property.refine'_3.h
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
m : S.pt ⟶ (pullbackCone f g).pt
h₁ : m ≫ PullbackCone.fst (pullbackCone f g) = PullbackCone.fst S
h₂ : m ≫ PullbackCone.snd (pullbackCone f g) = PullbackCone.snd S
x : ↑S.pt
⊢ m x =
    (ContinuousMap.mk fun x =>
        { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
          property :=
            (_ :
              f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) })
      x

Next tactic:
apply Subtype.ext
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · intro m h₁ h₂
        -- Porting note: used to be ext x
        apply ContinuousMap.ext; intro x
        apply Subtype.ext
        

Proof state:
case property.refine'_3.h.a
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
m : S.pt ⟶ (pullbackCone f g).pt
h₁ : m ≫ PullbackCone.fst (pullbackCone f g) = PullbackCone.fst S
h₂ : m ≫ PullbackCone.snd (pullbackCone f g) = PullbackCone.snd S
x : ↑S.pt
⊢ ↑(m x) =
    ↑((ContinuousMap.mk fun x =>
          { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
            property :=
              (_ :
                f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                  g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) })
        x)

Next tactic:
apply Prod.ext
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · intro m h₁ h₂
        -- Porting note: used to be ext x
        apply ContinuousMap.ext; intro x
        apply Subtype.ext
        apply Prod.ext
        · 

Proof state:
case property.refine'_3.h.a.a
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
m : S.pt ⟶ (pullbackCone f g).pt
h₁ : m ≫ PullbackCone.fst (pullbackCone f g) = PullbackCone.fst S
h₂ : m ≫ PullbackCone.snd (pullbackCone f g) = PullbackCone.snd S
x : ↑S.pt
⊢ (↑(m x)).1 =
    (↑((ContinuousMap.mk fun x =>
            { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
              property :=
                (_ :
                  f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                    g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) })
          x)).1

Next tactic:
simpa using ConcreteCategory.congr_hom h₁ x
/-- The constructed cone is a limit. -/
def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) :=
  PullbackCone.isLimitAux' _
    (by
      intro S
      constructor; swap
      exact
        { toFun := fun x =>
            ⟨⟨S.fst x, S.snd x⟩, by simpa using ConcreteCategory.congr_hom S.condition x⟩
          continuous_toFun := by
            apply Continuous.subtype_mk <| Continuous.prod_mk ?_ ?_
            · exact (PullbackCone.fst S)|>.continuous_toFun
            · exact (PullbackCone.snd S)|>.continuous_toFun
        }
      refine' ⟨_, _, _⟩
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · delta pullbackCone
        ext a
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        erw [comp_apply, ContinuousMap.coe_mk]
      · intro m h₁ h₂
        -- Porting note: used to be ext x
        apply ContinuousMap.ext; intro x
        apply Subtype.ext
        apply Prod.ext
        · simpa using ConcreteCategory.congr_hom h₁ x
        · 

Proof state:
case property.refine'_3.h.a.a
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
S : PullbackCone f g
m : S.pt ⟶ (pullbackCone f g).pt
h₁ : m ≫ PullbackCone.fst (pullbackCone f g) = PullbackCone.fst S
h₂ : m ≫ PullbackCone.snd (pullbackCone f g) = PullbackCone.snd S
x : ↑S.pt
⊢ (↑(m x)).2 =
    (↑((ContinuousMap.mk fun x =>
            { val := ((PullbackCone.fst S) x, (PullbackCone.snd S) x),
              property :=
                (_ :
                  f ((PullbackCone.fst S) x, (PullbackCone.snd S) x).1 =
                    g ((PullbackCone.fst S) x, (PullbackCone.snd S) x).2) })
          x)).2

Next tactic:
simpa using ConcreteCategory.congr_hom h₂ x
@[reassoc (attr := simp)]
theorem pullbackIsoProdSubtype_inv_fst (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullbackIsoProdSubtype f g).inv ≫ pullback.fst = pullbackFst f g := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackIsoProdSubtype f g).inv ≫ pullback.fst = pullbackFst f g

Next tactic:
simp [pullbackCone, pullbackIsoProdSubtype]
@[reassoc (attr := simp)]
theorem pullbackIsoProdSubtype_inv_snd (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullbackIsoProdSubtype f g).inv ≫ pullback.snd = pullbackSnd f g := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackIsoProdSubtype f g).inv ≫ pullback.snd = pullbackSnd f g

Next tactic:
simp [pullbackCone, pullbackIsoProdSubtype]
theorem pullbackIsoProdSubtype_hom_fst (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullbackIsoProdSubtype f g).hom ≫ pullbackFst f g = pullback.fst := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackIsoProdSubtype f g).hom ≫ pullbackFst f g = pullback.fst

Next tactic:
rw [← Iso.eq_inv_comp, pullbackIsoProdSubtype_inv_fst]
theorem pullbackIsoProdSubtype_hom_snd (f : X ⟶ Z) (g : Y ⟶ Z) :
    (pullbackIsoProdSubtype f g).hom ≫ pullbackSnd f g = pullback.snd := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
⊢ (pullbackIsoProdSubtype f g).hom ≫ pullbackSnd f g = pullback.snd

Next tactic:
rw [← Iso.eq_inv_comp, pullbackIsoProdSubtype_inv_snd]
@[simp]
theorem pullbackIsoProdSubtype_hom_apply {f : X ⟶ Z} {g : Y ⟶ Z}
    (x : ConcreteCategory.forget.obj (pullback f g)) :
    (pullbackIsoProdSubtype f g).hom x =
      ⟨⟨(pullback.fst : pullback f g ⟶ _) x, (pullback.snd : pullback f g ⟶ _) x⟩, by
        

Proof state:
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
x : ConcreteCategory.forget.obj (pullback f g)
⊢ f (pullback.fst x, pullback.snd x).1 = g (pullback.fst x, pullback.snd x).2

Next tactic:
simpa using ConcreteCategory.congr_hom pullback.condition x
@[simp]
theorem pullbackIsoProdSubtype_hom_apply {f : X ⟶ Z} {g : Y ⟶ Z}
    (x : ConcreteCategory.forget.obj (pullback f g)) :
    (pullbackIsoProdSubtype f g).hom x =
      ⟨⟨(pullback.fst : pullback f g ⟶ _) x, (pullback.snd : pullback f g ⟶ _) x⟩, by
        simpa using ConcreteCategory.congr_hom pullback.condition x⟩ := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
x : ConcreteCategory.forget.obj (pullback f g)
⊢ (pullbackIsoProdSubtype f g).hom x =
    { val := (pullback.fst x, pullback.snd x),
      property := (_ : f (pullback.fst x, pullback.snd x).1 = g (pullback.fst x, pullback.snd x).2) }

Next tactic:
apply Subtype.ext
@[simp]
theorem pullbackIsoProdSubtype_hom_apply {f : X ⟶ Z} {g : Y ⟶ Z}
    (x : ConcreteCategory.forget.obj (pullback f g)) :
    (pullbackIsoProdSubtype f g).hom x =
      ⟨⟨(pullback.fst : pullback f g ⟶ _) x, (pullback.snd : pullback f g ⟶ _) x⟩, by
        simpa using ConcreteCategory.congr_hom pullback.condition x⟩ := by
  apply Subtype.ext; 

Proof state:
case a
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
x : ConcreteCategory.forget.obj (pullback f g)
⊢ ↑((pullbackIsoProdSubtype f g).hom x) =
    ↑{ val := (pullback.fst x, pullback.snd x),
        property := (_ : f (pullback.fst x, pullback.snd x).1 = g (pullback.fst x, pullback.snd x).2) }

Next tactic:
apply Prod.ext
@[simp]
theorem pullbackIsoProdSubtype_hom_apply {f : X ⟶ Z} {g : Y ⟶ Z}
    (x : ConcreteCategory.forget.obj (pullback f g)) :
    (pullbackIsoProdSubtype f g).hom x =
      ⟨⟨(pullback.fst : pullback f g ⟶ _) x, (pullback.snd : pullback f g ⟶ _) x⟩, by
        simpa using ConcreteCategory.congr_hom pullback.condition x⟩ := by
  apply Subtype.ext; apply Prod.ext
  

Proof state:
case a.a
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
x : ConcreteCategory.forget.obj (pullback f g)
⊢ (↑((pullbackIsoProdSubtype f g).hom x)).1 =
    (↑{ val := (pullback.fst x, pullback.snd x),
          property := (_ : f (pullback.fst x, pullback.snd x).1 = g (pullback.fst x, pullback.snd x).2) }).1
case a.a
J : Type v
inst✝ : SmallCategory J
X Y Z : TopCat
f : X ⟶ Z
g : Y ⟶ Z
x : ConcreteCategory.forget.obj (pullback f g)
⊢ (↑((pullbackIsoProdSubtype f g).hom x)).2 =
    (↑{ val := (pullback.fst x, pullback.snd x),
          property := (_ : f (pullback.fst x, pullback.snd x).1 = g (pullback.fst x, pullback.snd x).2) }).2

Next tactic:
exacts [ConcreteCategory.congr_hom (pullbackIsoProdSubtype_hom_fst f g) x,
    ConcreteCategory.congr_hom (pullbackIsoProdSubtype_hom_snd f g) x]