Theorem: Profinite.epi_iff_surjective
File: Mathlib/Topology/Category/Profinite/Basic.lean

tactic: constructor
state_before: X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Epi f ↔ Function.Surjective ⇑f
state_after: case mp
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Epi f → Function.Surjective ⇑f

case mpr
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Function.Surjective ⇑f → Epi f

tactic: dsimp [Function.Surjective]
state_before: case mp
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Epi f → Function.Surjective ⇑f
state_after: case mp
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Epi f → ∀ (b : (forget Profinite).obj Y), ∃ a, f a = b

tactic: contrapose!
state_before: case mp
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Epi f → ∀ (b : (forget Profinite).obj Y), ∃ a, f a = b
state_after: case mp
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ (∃ b, ∀ (a : (forget Profinite).obj X), f a ≠ b) → ¬Epi f

tactic: rintro ⟨y, hy⟩ hf
state_before: case mp
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ (∃ b, ∀ (a : (forget Profinite).obj X), f a ≠ b) → ¬Epi f
state_after: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
⊢ False

tactic: let C := Set.range f
state_before: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
⊢ False
state_after: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
⊢ False

tactic: have hC : IsClosed C := (isCompact_range f.continuous).isClosed
state_before: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
⊢ False
state_after: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
⊢ False

tactic: let U := Cᶜ
state_before: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
⊢ False
state_after: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
⊢ False

tactic: have hyU : y ∈ U := by
  refine Set.mem_compl ?_
  rintro ⟨y', hy'⟩
  exact hy y' hy'
state_before: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
⊢ False
state_after: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
⊢ False

tactic: have hUy : U ∈ 𝓝 y := hC.compl_mem_nhds hyU
state_before: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
⊢ False
state_after: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
⊢ False

tactic: obtain ⟨V, hV, hyV, hVU⟩ := isTopologicalBasis_isClopen.mem_nhds_iff.mp hUy
state_before: case mp.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
⊢ False
state_after: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
⊢ False

tactic: classical
  let Z := of (ULift.{u} <| Fin 2)
  let g : Y ⟶ Z := ⟨(LocallyConstant.ofIsClopen hV).map ULift.up, LocallyConstant.continuous _⟩
  let h : Y ⟶ Z := ⟨fun _ => ⟨1⟩, continuous_const⟩
  have H : h = g := by
    rw [← cancel_epi f]
    ext x
    apply ULift.ext
    dsimp [g, LocallyConstant.ofIsClopen]
    erw [comp_apply, ContinuousMap.coe_mk, comp_apply, ContinuousMap.coe_mk,
      Function.comp_apply, if_neg]
    refine mt (fun α => hVU α) ?_
    simp only [U, C, Set.mem_range_self, not_true, not_false_iff, Set.mem_compl_iff]
  apply_fun fun e => (e y).down at H
  dsimp [g, LocallyConstant.ofIsClopen] at H
  erw [ContinuousMap.coe_mk, ContinuousMap.coe_mk, Function.comp_apply, if_pos hyV] at H
  exact top_ne_bot H
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
⊢ False
state_after: no goals

tactic: refine Set.mem_compl ?_
state_before: X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
⊢ y ∈ U
state_after: X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
⊢ y ∉ C

tactic: rintro ⟨y', hy'⟩
state_before: X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
⊢ y ∉ C
state_after: case intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
y' : (forget Profinite).obj X
hy' : f y' = y
⊢ False

tactic: exact hy y' hy'
state_before: case intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
y' : (forget Profinite).obj X
hy' : f y' = y
⊢ False
state_after: no goals

tactic: let Z := of (ULift.{u} <| Fin 2)
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
⊢ False
state_after: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
⊢ False

tactic: let g : Y ⟶ Z := ⟨(LocallyConstant.ofIsClopen hV).map ULift.up, LocallyConstant.continuous _⟩
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
⊢ False
state_after: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
⊢ False

tactic: let h : Y ⟶ Z := ⟨fun _ => ⟨1⟩, continuous_const⟩
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
⊢ False
state_after: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
⊢ False

tactic: have H : h = g := by
  rw [← cancel_epi f]
  ext x
  apply ULift.ext
  dsimp [g, LocallyConstant.ofIsClopen]
  erw [comp_apply, ContinuousMap.coe_mk, comp_apply, ContinuousMap.coe_mk,
    Function.comp_apply, if_neg]
  refine mt (fun α => hVU α) ?_
  simp only [U, C, Set.mem_range_self, not_true, not_false_iff, Set.mem_compl_iff]
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
⊢ False
state_after: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
H : h = g
⊢ False

tactic: apply_fun fun e => (e y).down at H
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
H : h = g
⊢ False
state_after: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
H : (h y).down = (g y).down
⊢ False

tactic: dsimp [g, LocallyConstant.ofIsClopen] at H
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
H : (h y).down = (g y).down
⊢ False
state_after: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
H : (h y).down = ({ toFun := ULift.up ∘ fun x => if x ∈ V then 0 else 1, continuous_toFun := ⋯ } y).down
⊢ False

tactic: erw [ContinuousMap.coe_mk, ContinuousMap.coe_mk, Function.comp_apply, if_pos hyV] at H
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
H : (h y).down = ({ toFun := ULift.up ∘ fun x => if x ∈ V then 0 else 1, continuous_toFun := ⋯ } y).down
⊢ False
state_after: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
H : { down := 1 }.down = { down := 0 }.down
⊢ False

tactic: exact top_ne_bot H
state_before: case mp.intro.intro.intro.intro
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
H : { down := 1 }.down = { down := 0 }.down
⊢ False
state_after: no goals

tactic: rw [← cancel_epi f]
state_before: X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
⊢ h = g
state_after: X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
⊢ f ≫ h = f ≫ g

tactic: ext x
state_before: X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
⊢ f ≫ h = f ≫ g
state_after: case w
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ (f ≫ h) x = (f ≫ g) x

tactic: apply ULift.ext
state_before: case w
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ (f ≫ h) x = (f ≫ g) x
state_after: case w.h
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ ((f ≫ h) x).down = ((f ≫ g) x).down

tactic: dsimp [g, LocallyConstant.ofIsClopen]
state_before: case w.h
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ ((f ≫ h) x).down = ((f ≫ g) x).down
state_after: case w.h
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ ((f ≫ h) x).down = ((f ≫ { toFun := ULift.up ∘ fun x => if x ∈ V then 0 else 1, continuous_toFun := ⋯ }) x).down

tactic: erw [comp_apply, ContinuousMap.coe_mk, comp_apply, ContinuousMap.coe_mk,
  Function.comp_apply, if_neg]
state_before: case w.h
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ ((f ≫ h) x).down = ((f ≫ { toFun := ULift.up ∘ fun x => if x ∈ V then 0 else 1, continuous_toFun := ⋯ }) x).down
state_after: case w.h.hnc
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ f x ∉ V

tactic: refine mt (fun α => hVU α) ?_
state_before: case w.h.hnc
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ f x ∉ V
state_after: case w.h.hnc
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ f x ∉ U

tactic: simp only [U, C, Set.mem_range_self, not_true, not_false_iff, Set.mem_compl_iff]
state_before: case w.h.hnc
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
y : (forget Profinite).obj Y
hy : ∀ (a : (forget Profinite).obj X), f a ≠ y
hf : Epi f
C : Set ((forget Profinite).obj Y) := Set.range ⇑f
hC : IsClosed C
U : Set ((forget Profinite).obj Y) := Cᶜ
hyU : y ∈ U
hUy : U ∈ 𝓝 y
V : Set ((forget Profinite).obj Y)
hV : V ∈ {s | IsClopen s}
hyV : y ∈ V
hVU : V ⊆ U
Z : Profinite := of (ULift.{u, 0} (Fin 2))
g : Y ⟶ Z := { toFun := ⇑(LocallyConstant.map ULift.up (LocallyConstant.ofIsClopen hV)), continuous_toFun := ⋯ }
h : Y ⟶ Z := { toFun := fun x => { down := 1 }, continuous_toFun := ⋯ }
x : (forget Profinite).obj X
⊢ f x ∉ U
state_after: no goals

tactic: rw [← CategoryTheory.epi_iff_surjective]
state_before: case mpr
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Function.Surjective ⇑f → Epi f
state_after: case mpr
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Epi ⇑f → Epi f

tactic: apply (forget Profinite).epi_of_epi_map
state_before: case mpr
X✝ Y✝ : Profinite
f✝ : X✝ ⟶ Y✝
X Y : Profinite
f : X ⟶ Y
⊢ Epi ⇑f → Epi f
state_after: no goals