l3lab/ntp-mathlib huggingface dataset:
/-- A skyscraper presheaf is a presheaf supported at a single point: if `p₀ ∈ X` is a specified
point, then the skyscraper presheaf `𝓕` with value `A` is defined by `U ↦ A` if `p₀ ∈ U` and
`U ↦ *` if `p₀ ∉ A` where `*` is some terminal object.
-/
@[simps]
def skyscraperPresheaf : Presheaf C X where
  obj U := if p₀ ∈ unop U then A else terminal C
  map {U V} i :=
    if h : p₀ ∈ unop V then eqToHom <| by dsimp; erw [if_pos h, if_pos (leOfHom i.unop h)]
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  map_id U :=
    (em (p₀ ∈ U.unop)).elim (fun h => dif_pos h) fun h =>
      ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext _ _
  map_comp {U V W} iVU iWV := by
    

Proof state:
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
U V W : (Opens ↑X)ᵒᵖ
iVU : U ⟶ V
iWV : V ⟶ W
⊢ { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
          map := fun {U V} i =>
            if h : p₀ ∈ V.unop then
              eqToHom (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
            else
              IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
      (iVU ≫ iWV) =
    { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
            map := fun {U V} i =>
              if h : p₀ ∈ V.unop then
                eqToHom
                  (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
              else
                IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                  ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
        iVU ≫
      { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
            map := fun {U V} i =>
              if h : p₀ ∈ V.unop then
                eqToHom
                  (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
              else
                IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                  ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
        iWV

Next tactic:
by_cases hW : p₀ ∈ unop W
/-- A skyscraper presheaf is a presheaf supported at a single point: if `p₀ ∈ X` is a specified
point, then the skyscraper presheaf `𝓕` with value `A` is defined by `U ↦ A` if `p₀ ∈ U` and
`U ↦ *` if `p₀ ∉ A` where `*` is some terminal object.
-/
@[simps]
def skyscraperPresheaf : Presheaf C X where
  obj U := if p₀ ∈ unop U then A else terminal C
  map {U V} i :=
    if h : p₀ ∈ unop V then eqToHom <| by dsimp; erw [if_pos h, if_pos (leOfHom i.unop h)]
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  map_id U :=
    (em (p₀ ∈ U.unop)).elim (fun h => dif_pos h) fun h =>
      ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext _ _
  map_comp {U V W} iVU iWV := by
    by_cases hW : p₀ ∈ unop W
    · 

Proof state:
case pos
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
U V W : (Opens ↑X)ᵒᵖ
iVU : U ⟶ V
iWV : V ⟶ W
hW : p₀ ∈ W.unop
⊢ { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
          map := fun {U V} i =>
            if h : p₀ ∈ V.unop then
              eqToHom (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
            else
              IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
      (iVU ≫ iWV) =
    { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
            map := fun {U V} i =>
              if h : p₀ ∈ V.unop then
                eqToHom
                  (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
              else
                IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                  ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
        iVU ≫
      { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
            map := fun {U V} i =>
              if h : p₀ ∈ V.unop then
                eqToHom
                  (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
              else
                IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                  ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
        iWV

Next tactic:
have hV : p₀ ∈ unop V := leOfHom iWV.unop hW
/-- A skyscraper presheaf is a presheaf supported at a single point: if `p₀ ∈ X` is a specified
point, then the skyscraper presheaf `𝓕` with value `A` is defined by `U ↦ A` if `p₀ ∈ U` and
`U ↦ *` if `p₀ ∉ A` where `*` is some terminal object.
-/
@[simps]
def skyscraperPresheaf : Presheaf C X where
  obj U := if p₀ ∈ unop U then A else terminal C
  map {U V} i :=
    if h : p₀ ∈ unop V then eqToHom <| by dsimp; erw [if_pos h, if_pos (leOfHom i.unop h)]
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  map_id U :=
    (em (p₀ ∈ U.unop)).elim (fun h => dif_pos h) fun h =>
      ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext _ _
  map_comp {U V W} iVU iWV := by
    by_cases hW : p₀ ∈ unop W
    · have hV : p₀ ∈ unop V := leOfHom iWV.unop hW
      

Proof state:
case pos
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
U V W : (Opens ↑X)ᵒᵖ
iVU : U ⟶ V
iWV : V ⟶ W
hW : p₀ ∈ W.unop
hV : p₀ ∈ V.unop
⊢ { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
          map := fun {U V} i =>
            if h : p₀ ∈ V.unop then
              eqToHom (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
            else
              IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
      (iVU ≫ iWV) =
    { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
            map := fun {U V} i =>
              if h : p₀ ∈ V.unop then
                eqToHom
                  (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
              else
                IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                  ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
        iVU ≫
      { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
            map := fun {U V} i =>
              if h : p₀ ∈ V.unop then
                eqToHom
                  (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
              else
                IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                  ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
        iWV

Next tactic:
simp only [dif_pos hW, dif_pos hV, eqToHom_trans]
/-- A skyscraper presheaf is a presheaf supported at a single point: if `p₀ ∈ X` is a specified
point, then the skyscraper presheaf `𝓕` with value `A` is defined by `U ↦ A` if `p₀ ∈ U` and
`U ↦ *` if `p₀ ∉ A` where `*` is some terminal object.
-/
@[simps]
def skyscraperPresheaf : Presheaf C X where
  obj U := if p₀ ∈ unop U then A else terminal C
  map {U V} i :=
    if h : p₀ ∈ unop V then eqToHom <| by dsimp; erw [if_pos h, if_pos (leOfHom i.unop h)]
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  map_id U :=
    (em (p₀ ∈ U.unop)).elim (fun h => dif_pos h) fun h =>
      ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext _ _
  map_comp {U V W} iVU iWV := by
    by_cases hW : p₀ ∈ unop W
    · have hV : p₀ ∈ unop V := leOfHom iWV.unop hW
      simp only [dif_pos hW, dif_pos hV, eqToHom_trans]
    · 

Proof state:
case neg
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
U V W : (Opens ↑X)ᵒᵖ
iVU : U ⟶ V
iWV : V ⟶ W
hW : p₀ ∉ W.unop
⊢ { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
          map := fun {U V} i =>
            if h : p₀ ∈ V.unop then
              eqToHom (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
            else
              IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
      (iVU ≫ iWV) =
    { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
            map := fun {U V} i =>
              if h : p₀ ∈ V.unop then
                eqToHom
                  (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
              else
                IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                  ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
        iVU ≫
      { obj := fun U => if p₀ ∈ U.unop then A else ⊤_ C,
            map := fun {U V} i =>
              if h : p₀ ∈ V.unop then
                eqToHom
                  (_ : (fun U => if p₀ ∈ U.unop then A else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then A else ⊤_ C) V)
              else
                IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
                  ((fun U => if p₀ ∈ U.unop then A else ⊤_ C) U) }.map
        iWV

Next tactic:
dsimp
/-- A skyscraper presheaf is a presheaf supported at a single point: if `p₀ ∈ X` is a specified
point, then the skyscraper presheaf `𝓕` with value `A` is defined by `U ↦ A` if `p₀ ∈ U` and
`U ↦ *` if `p₀ ∉ A` where `*` is some terminal object.
-/
@[simps]
def skyscraperPresheaf : Presheaf C X where
  obj U := if p₀ ∈ unop U then A else terminal C
  map {U V} i :=
    if h : p₀ ∈ unop V then eqToHom <| by dsimp; erw [if_pos h, if_pos (leOfHom i.unop h)]
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  map_id U :=
    (em (p₀ ∈ U.unop)).elim (fun h => dif_pos h) fun h =>
      ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext _ _
  map_comp {U V W} iVU iWV := by
    by_cases hW : p₀ ∈ unop W
    · have hV : p₀ ∈ unop V := leOfHom iWV.unop hW
      simp only [dif_pos hW, dif_pos hV, eqToHom_trans]
    · dsimp; 

Proof state:
case neg
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
U V W : (Opens ↑X)ᵒᵖ
iVU : U ⟶ V
iWV : V ⟶ W
hW : p₀ ∉ W.unop
⊢ (if h : p₀ ∈ W.unop then eqToHom (_ : (if p₀ ∈ U.unop then A else ⊤_ C) = if p₀ ∈ W.unop then A else ⊤_ C)
    else
      IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ W.unop then A else ⊤_ C) ▸ terminalIsTerminal)
        (if p₀ ∈ U.unop then A else ⊤_ C)) =
    (if h : p₀ ∈ V.unop then eqToHom (_ : (if p₀ ∈ U.unop then A else ⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ U.unop then A else ⊤_ C)) ≫
      if h : p₀ ∈ W.unop then eqToHom (_ : (if p₀ ∈ V.unop then A else ⊤_ C) = if p₀ ∈ W.unop then A else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ W.unop then A else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ V.unop then A else ⊤_ C)

Next tactic:
rw [dif_neg hW]
/-- A skyscraper presheaf is a presheaf supported at a single point: if `p₀ ∈ X` is a specified
point, then the skyscraper presheaf `𝓕` with value `A` is defined by `U ↦ A` if `p₀ ∈ U` and
`U ↦ *` if `p₀ ∉ A` where `*` is some terminal object.
-/
@[simps]
def skyscraperPresheaf : Presheaf C X where
  obj U := if p₀ ∈ unop U then A else terminal C
  map {U V} i :=
    if h : p₀ ∈ unop V then eqToHom <| by dsimp; erw [if_pos h, if_pos (leOfHom i.unop h)]
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  map_id U :=
    (em (p₀ ∈ U.unop)).elim (fun h => dif_pos h) fun h =>
      ((if_neg h).symm.ndrec terminalIsTerminal).hom_ext _ _
  map_comp {U V W} iVU iWV := by
    by_cases hW : p₀ ∈ unop W
    · have hV : p₀ ∈ unop V := leOfHom iWV.unop hW
      simp only [dif_pos hW, dif_pos hV, eqToHom_trans]
    · dsimp; rw [dif_neg hW]; 

Proof state:
case neg
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
U V W : (Opens ↑X)ᵒᵖ
iVU : U ⟶ V
iWV : V ⟶ W
hW : p₀ ∉ W.unop
⊢ IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ W.unop then A else ⊤_ C) ▸ terminalIsTerminal)
      (if p₀ ∈ U.unop then A else ⊤_ C) =
    (if h : p₀ ∈ V.unop then eqToHom (_ : (if p₀ ∈ U.unop then A else ⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then A else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ U.unop then A else ⊤_ C)) ≫
      if h : p₀ ∈ W.unop then eqToHom (_ : (if p₀ ∈ V.unop then A else ⊤_ C) = if p₀ ∈ W.unop then A else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ W.unop then A else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ V.unop then A else ⊤_ C)

Next tactic:
apply ((if_neg hW).symm.ndrec terminalIsTerminal).hom_ext
theorem skyscraperPresheaf_eq_pushforward
    [hd : ∀ U : Opens (TopCat.of PUnit.{u + 1}), Decidable (PUnit.unit ∈ U)] :
    skyscraperPresheaf p₀ A =
      ContinuousMap.const (TopCat.of PUnit) p₀ _*
        skyscraperPresheaf (X := TopCat.of PUnit) PUnit.unit A := by
  

Proof state:
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
hd : (U : Opens ↑(of PUnit.{u + 1})) → Decidable (PUnit.unit ∈ U)
⊢ skyscraperPresheaf p₀ A = ContinuousMap.const (↑(of PUnit.{u + 1})) p₀ _* skyscraperPresheaf PUnit.unit A

Next tactic:
convert_to @skyscraperPresheaf X p₀ (fun U => hd <| (Opens.map <| ContinuousMap.const _ p₀).obj U)
    C _ _ A = _
theorem skyscraperPresheaf_eq_pushforward
    [hd : ∀ U : Opens (TopCat.of PUnit.{u + 1}), Decidable (PUnit.unit ∈ U)] :
    skyscraperPresheaf p₀ A =
      ContinuousMap.const (TopCat.of PUnit) p₀ _*
        skyscraperPresheaf (X := TopCat.of PUnit) PUnit.unit A := by
  convert_to @skyscraperPresheaf X p₀ (fun U => hd <| (Opens.map <| ContinuousMap.const _ p₀).obj U)
    C _ _ A = _ <;> 

Proof state:
case h.e'_2
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
hd : (U : Opens ↑(of PUnit.{u + 1})) → Decidable (PUnit.unit ∈ U)
⊢ skyscraperPresheaf p₀ A = skyscraperPresheaf p₀ A

Next tactic:
congr
theorem skyscraperPresheaf_eq_pushforward
    [hd : ∀ U : Opens (TopCat.of PUnit.{u + 1}), Decidable (PUnit.unit ∈ U)] :
    skyscraperPresheaf p₀ A =
      ContinuousMap.const (TopCat.of PUnit) p₀ _*
        skyscraperPresheaf (X := TopCat.of PUnit) PUnit.unit A := by
  convert_to @skyscraperPresheaf X p₀ (fun U => hd <| (Opens.map <| ContinuousMap.const _ p₀).obj U)
    C _ _ A = _ <;> 

Proof state:
case convert_2
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A : C
hd : (U : Opens ↑(of PUnit.{u + 1})) → Decidable (PUnit.unit ∈ U)
⊢ skyscraperPresheaf p₀ A = ContinuousMap.const (↑(of PUnit.{u + 1})) p₀ _* skyscraperPresheaf PUnit.unit A

Next tactic:
congr
/-- Taking skyscraper presheaf at a point is functorial: `c ↦ skyscraper p₀ c` defines a functor by
sending every `f : a ⟶ b` to the natural transformation `α` defined as: `α(U) = f : a ⟶ b` if
`p₀ ∈ U` and the unique morphism to a terminal object in `C` if `p₀ ∉ U`.
-/
@[simps]
def SkyscraperPresheafFunctor.map' {a b : C} (f : a ⟶ b) :
    skyscraperPresheaf p₀ a ⟶ skyscraperPresheaf p₀ b where
  app U :=
    if h : p₀ ∈ U.unop then eqToHom (if_pos h) ≫ f ≫ eqToHom (if_pos h).symm
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  naturality U V i := by
    

Proof state:
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A a b : C
f : a ⟶ b
U V : (Opens ↑X)ᵒᵖ
i : U ⟶ V
⊢ (skyscraperPresheaf p₀ a).map i ≫
      (fun U =>
          if h : p₀ ∈ U.unop then
            eqToHom (_ : (if p₀ ∈ U.unop then a else ⊤_ C) = a) ≫ f ≫ eqToHom (_ : b = if p₀ ∈ U.unop then b else ⊤_ C)
          else
            IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ U.unop then b else ⊤_ C) ▸ terminalIsTerminal)
              ((skyscraperPresheaf p₀ a).obj U))
        V =
    (fun U =>
          if h : p₀ ∈ U.unop then
            eqToHom (_ : (if p₀ ∈ U.unop then a else ⊤_ C) = a) ≫ f ≫ eqToHom (_ : b = if p₀ ∈ U.unop then b else ⊤_ C)
          else
            IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ U.unop then b else ⊤_ C) ▸ terminalIsTerminal)
              ((skyscraperPresheaf p₀ a).obj U))
        U ≫
      (skyscraperPresheaf p₀ b).map i

Next tactic:
simp only [skyscraperPresheaf_map]
/-- Taking skyscraper presheaf at a point is functorial: `c ↦ skyscraper p₀ c` defines a functor by
sending every `f : a ⟶ b` to the natural transformation `α` defined as: `α(U) = f : a ⟶ b` if
`p₀ ∈ U` and the unique morphism to a terminal object in `C` if `p₀ ∉ U`.
-/
@[simps]
def SkyscraperPresheafFunctor.map' {a b : C} (f : a ⟶ b) :
    skyscraperPresheaf p₀ a ⟶ skyscraperPresheaf p₀ b where
  app U :=
    if h : p₀ ∈ U.unop then eqToHom (if_pos h) ≫ f ≫ eqToHom (if_pos h).symm
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  naturality U V i := by
    simp only [skyscraperPresheaf_map]; 

Proof state:
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A a b : C
f : a ⟶ b
U V : (Opens ↑X)ᵒᵖ
i : U ⟶ V
⊢ ((if h : p₀ ∈ V.unop then
        eqToHom (_ : (fun U => if p₀ ∈ U.unop then a else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then a else ⊤_ C) V)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then a else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ U.unop then a else ⊤_ C)) ≫
      if h : p₀ ∈ V.unop then
        eqToHom (_ : (if p₀ ∈ V.unop then a else ⊤_ C) = a) ≫ f ≫ eqToHom (_ : b = if p₀ ∈ V.unop then b else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          ((skyscraperPresheaf p₀ a).obj V)) =
    (if h : p₀ ∈ U.unop then
        eqToHom (_ : (if p₀ ∈ U.unop then a else ⊤_ C) = a) ≫ f ≫ eqToHom (_ : b = if p₀ ∈ U.unop then b else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ U.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          ((skyscraperPresheaf p₀ a).obj U)) ≫
      if h : p₀ ∈ V.unop then
        eqToHom (_ : (fun U => if p₀ ∈ U.unop then b else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then b else ⊤_ C) V)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ U.unop then b else ⊤_ C)

Next tactic:
by_cases hV : p₀ ∈ V.unop
/-- Taking skyscraper presheaf at a point is functorial: `c ↦ skyscraper p₀ c` defines a functor by
sending every `f : a ⟶ b` to the natural transformation `α` defined as: `α(U) = f : a ⟶ b` if
`p₀ ∈ U` and the unique morphism to a terminal object in `C` if `p₀ ∉ U`.
-/
@[simps]
def SkyscraperPresheafFunctor.map' {a b : C} (f : a ⟶ b) :
    skyscraperPresheaf p₀ a ⟶ skyscraperPresheaf p₀ b where
  app U :=
    if h : p₀ ∈ U.unop then eqToHom (if_pos h) ≫ f ≫ eqToHom (if_pos h).symm
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  naturality U V i := by
    simp only [skyscraperPresheaf_map]; by_cases hV : p₀ ∈ V.unop
    · 

Proof state:
case pos
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A a b : C
f : a ⟶ b
U V : (Opens ↑X)ᵒᵖ
i : U ⟶ V
hV : p₀ ∈ V.unop
⊢ ((if h : p₀ ∈ V.unop then
        eqToHom (_ : (fun U => if p₀ ∈ U.unop then a else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then a else ⊤_ C) V)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then a else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ U.unop then a else ⊤_ C)) ≫
      if h : p₀ ∈ V.unop then
        eqToHom (_ : (if p₀ ∈ V.unop then a else ⊤_ C) = a) ≫ f ≫ eqToHom (_ : b = if p₀ ∈ V.unop then b else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          ((skyscraperPresheaf p₀ a).obj V)) =
    (if h : p₀ ∈ U.unop then
        eqToHom (_ : (if p₀ ∈ U.unop then a else ⊤_ C) = a) ≫ f ≫ eqToHom (_ : b = if p₀ ∈ U.unop then b else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ U.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          ((skyscraperPresheaf p₀ a).obj U)) ≫
      if h : p₀ ∈ V.unop then
        eqToHom (_ : (fun U => if p₀ ∈ U.unop then b else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then b else ⊤_ C) V)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ U.unop then b else ⊤_ C)

Next tactic:
have hU : p₀ ∈ U.unop := leOfHom i.unop hV
/-- Taking skyscraper presheaf at a point is functorial: `c ↦ skyscraper p₀ c` defines a functor by
sending every `f : a ⟶ b` to the natural transformation `α` defined as: `α(U) = f : a ⟶ b` if
`p₀ ∈ U` and the unique morphism to a terminal object in `C` if `p₀ ∉ U`.
-/
@[simps]
def SkyscraperPresheafFunctor.map' {a b : C} (f : a ⟶ b) :
    skyscraperPresheaf p₀ a ⟶ skyscraperPresheaf p₀ b where
  app U :=
    if h : p₀ ∈ U.unop then eqToHom (if_pos h) ≫ f ≫ eqToHom (if_pos h).symm
    else ((if_neg h).symm.ndrec terminalIsTerminal).from _
  naturality U V i := by
    simp only [skyscraperPresheaf_map]; by_cases hV : p₀ ∈ V.unop
    · have hU : p₀ ∈ U.unop := leOfHom i.unop hV; 

Proof state:
case pos
X : TopCat
p₀ : ↑X
inst✝² : (U : Opens ↑X) → Decidable (p₀ ∈ U)
C : Type v
inst✝¹ : Category.{w, v} C
inst✝ : HasTerminal C
A a b : C
f : a ⟶ b
U V : (Opens ↑X)ᵒᵖ
i : U ⟶ V
hV : p₀ ∈ V.unop
hU : p₀ ∈ U.unop
⊢ ((if h : p₀ ∈ V.unop then
        eqToHom (_ : (fun U => if p₀ ∈ U.unop then a else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then a else ⊤_ C) V)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then a else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ U.unop then a else ⊤_ C)) ≫
      if h : p₀ ∈ V.unop then
        eqToHom (_ : (if p₀ ∈ V.unop then a else ⊤_ C) = a) ≫ f ≫ eqToHom (_ : b = if p₀ ∈ V.unop then b else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          ((skyscraperPresheaf p₀ a).obj V)) =
    (if h : p₀ ∈ U.unop then
        eqToHom (_ : (if p₀ ∈ U.unop then a else ⊤_ C) = a) ≫ f ≫ eqToHom (_ : b = if p₀ ∈ U.unop then b else ⊤_ C)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ U.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          ((skyscraperPresheaf p₀ a).obj U)) ≫
      if h : p₀ ∈ V.unop then
        eqToHom (_ : (fun U => if p₀ ∈ U.unop then b else ⊤_ C) U = (fun U => if p₀ ∈ U.unop then b else ⊤_ C) V)
      else
        IsTerminal.from ((_ : (⊤_ C) = if p₀ ∈ V.unop then b else ⊤_ C) ▸ terminalIsTerminal)
          (if p₀ ∈ U.unop then b else ⊤_ C)

Next tactic:
split_ifs