Prove2Me
Navigate
DiscoverFormalpediaBlogsUsersMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

Hatcher §1.3: covering spaces, p∗p_*p∗​ and H=p∗π1(X~)H=p_*\pi_1(\tilde X)H=p∗​π1​(X~), isomorphisms, deck transformations, normal covers, covering space actions

Definition
Hatcher_Covering

by korbonits · Sep 8, 2026 · Mathlib 0df444a (Lean v4.33.1)

algebraic-topologycovering-spacesfundamental-grouphatcher

This bundle fixes the objects of Hatcher, Section 1.3 (pp. 56–72), in the book-wide namespace Hatcher. A covering space of XXX is a map p:X~→Xp:\tilde X\to Xp:X~→X satisfying Mathlib's IsCoveringMap (each x∈Xx\in Xx∈X has an evenly covered open neighborhood; p−1(U)p^{-1}(U)p−1(U) may be empty, so ppp need not be surjective, as on p. 56).

  1. IsSemilocallySimplyConnected X (p. 63): each x∈Xx\in Xx∈X has a neighborhood UUU such that every loop at xxx with image in UUU is null-homotopic in XXX, i.e. the inclusion-induced map π1(U,x)→π1(X,x)\pi_1(U,x)\to\pi_1(X,x)π1​(U,x)→π1​(X,x) is trivial.

  2. coverHom p hp he is p∗:π1(X~,x~0)→π1(X,x0)p_*:\pi_1(\tilde X,\tilde x_0)\to\pi_1(X,x_0)p∗​:π1​(X~,x~0​)→π1​(X,x0​) for a continuous ppp with p(x~0)=x0p(\tilde x_0)=x_0p(x~0​)=x0​, and coverSubgroup p hp he is its image H=p∗(π1(X~,x~0))≤π1(X,x0)H=p_*\big(\pi_1(\tilde X,\tilde x_0)\big)\le\pi_1(X,x_0)H=p∗​(π1​(X~,x~0​))≤π1​(X,x0​) (p. 61).

  3. deckGroup p is the group G(X~)G(\tilde X)G(X~) of deck transformations (p. 70): the homeomorphisms f:X~→X~f:\tilde X\to\tilde Xf:X~→X~ with p∘f=pp\circ f=pp∘f=p, as a subgroup of the group of self-homeomorphisms of X~\tilde XX~ under composition. IsNormalCover p (p. 70): for every pair x~,x~′\tilde x,\tilde x'x~,x~′ with p(x~)=p(x~′)p(\tilde x)=p(\tilde x')p(x~)=p(x~′) there is a deck transformation taking x~\tilde xx~ to x~′\tilde x'x~′.

  4. CoveringSpace X is a covering space of XXX as a structure: a total space X~\tilde XX~ (in the same universe as XXX), its topology, the map ppp and the proof that ppp is a covering map. PointedCover X x₀ adds a basepoint x~0\tilde x_0x~0​ with p(x~0)=x0p(\tilde x_0)=x_0p(x~0​)=x0​, and PointedCover.subgroup is the associated subgroup p∗π1(X~,x~0)p_*\pi_1(\tilde X,\tilde x_0)p∗​π1​(X~,x~0​) of Theorem 1.38.

  5. IsIsomorphic C₁ C₂ (p. 67): there is a homeomorphism f:X~1→X~2f:\tilde X_1\to\tilde X_2f:X~1​→X~2​ with p1=p2∘fp_1=p_2\circ fp1​=p2​∘f. IsPointedIsomorphic C₁ C₂: such an fff with moreover f(x~1)=x~2f(\tilde x_1)=\tilde x_2f(x~1​)=x~2​.

  6. IsCoveringSpaceAction G Y is Hatcher's condition (∗)(\ast)(∗) (p. 72) for an action of a group GGG on a space YYY: each ggg acts continuously (so by a homeomorphism), and each y∈Yy\in Yy∈Y has a neighborhood UUU with g(U)∩U≠∅g(U)\cap U\neq\varnothingg(U)∩U=∅ only for g=1g=1g=1, i.e. the translates g(U)g(U)g(U) are pairwise disjoint.

  7. OrbitSpace G Y is the orbit space Y/GY/GY/G (p. 72), the quotient of YYY by the orbit relation with the quotient topology, and orbitProj G Y is the quotient map p:Y→Y/Gp:Y\to Y/Gp:Y→Y/G, p(y)=Gyp(y)=Gyp(y)=Gy, with the (trivial) lemma that it is continuous.

Formalization Note Path-connectedness of covering spaces is not built into the structures; it is assumed where Hatcher assumes it. The subgroup HHH depends on the choice of basepoint x~0\tilde x_0x~0​ in the fibre, and is recorded through the proof he : p e₀ = x₀. The group law on E ≃ₜ E is composition, (f * g) e = f (g e).

Definition code
import Mathlib

/-!
Hatcher, *Algebraic Topology*, Section 1.3 "Covering Spaces" (pp. 56–72).

Objects appearing in the classification of covering spaces and in the theory of deck
transformations: semilocal simple connectivity (p. 63), the induced homomorphism
`p_* : π₁(X̃, x̃₀) → π₁(X, x₀)` and its image subgroup `H = p_*(π₁(X̃, x̃₀))` (p. 61),
covering spaces of `X` with and without basepoints and their isomorphisms (p. 67),
the deck transformation group `G(X̃)` and normal covering spaces (p. 70), and covering
space actions with their orbit spaces `Y/G` (p. 72).
-/

noncomputable section

namespace Hatcher

universe u

section SpaceProperties

variable (X : Type*) [TopologicalSpace X]

/-- Hatcher, p. 63: `X` is **semilocally simply-connected** if each point `x ∈ X` has a
neighborhood `U` such that the inclusion-induced map `π₁(U, x) → π₁(X, x)` is trivial, i.e.
every loop at `x` contained in `U` is null-homotopic in `X`. -/
def IsSemilocallySimplyConnected : Prop :=
  ∀ x : X, ∃ U ∈ nhds x, ∀ γ : Path x x, (∀ t, γ t ∈ U) → γ.Homotopic (Path.refl x)

end SpaceProperties

section CoveringMap

variable {E X : Type*} [TopologicalSpace E] [TopologicalSpace X] (p : E → X)

/-- `p_* : π₁(X̃, x̃₀) → π₁(X, x₀)`, the homomorphism induced by a covering space
`p : (X̃, x̃₀) → (X, x₀)` (Hatcher, p. 61). -/
def coverHom (hp : Continuous p) {e₀ : E} {x₀ : X} (he : p e₀ = x₀) :
    FundamentalGroup E e₀ →* FundamentalGroup X x₀ :=
  FundamentalGroup.mapOfEq ⟨p, hp⟩ he

/-- The image subgroup `H = p_*(π₁(X̃, x̃₀)) ⊆ π₁(X, x₀)` of a covering space
`p : (X̃, x̃₀) → (X, x₀)` (Hatcher, p. 61). -/
def coverSubgroup (hp : Continuous p) {e₀ : E} {x₀ : X} (he : p e₀ = x₀) :
    Subgroup (FundamentalGroup X x₀) :=
  (coverHom p hp he).range

/-- The group `G(X̃)` of **deck transformations** of `p : X̃ → X` (Hatcher, p. 70): the
homeomorphisms `f : X̃ → X̃` with `p ∘ f = p`, a subgroup of the group of all
self-homeomorphisms of `X̃` under composition. -/
def deckGroup : Subgroup (E ≃ₜ E) where
  carrier := {f | ∀ e, p (f e) = p e}
  mul_mem' {f g} hf hg e := by
    change p (f (g e)) = p e
    rw [hf, hg]
  one_mem' _ := rfl
  inv_mem' {f} hf e := by
    change p (f.symm e) = p e
    rw [← hf (f.symm e), f.apply_symm_apply]

/-- `p : X̃ → X` is a **normal** covering space (Hatcher, p. 70): for each `x ∈ X` and each
pair of lifts `x̃, x̃'` of `x` there is a deck transformation taking `x̃` to `x̃'`. -/
def IsNormalCover : Prop :=
  ∀ e e' : E, p e = p e' → ∃ f ∈ deckGroup p, f e = e'

end CoveringMap

section Classification

variable (X : Type u) [TopologicalSpace X]

/-- A **covering space** of `X` (Hatcher, p. 56): a space `X̃` together with a covering map
`p : X̃ → X`. -/
structure CoveringSpace where
  /-- The total space `X̃`. -/
  E : Type u
  [topE : TopologicalSpace E]
  /-- The covering map `p : X̃ → X`. -/
  p : E → X
  isCoveringMap : IsCoveringMap p

attribute [instance] CoveringSpace.topE

/-- A covering space `p : (X̃, x̃₀) → (X, x₀)` with a chosen basepoint `x̃₀ ∈ p⁻¹(x₀)`
(Hatcher, p. 61). -/
structure PointedCover (x₀ : X) extends CoveringSpace X where
  /-- The basepoint `x̃₀ ∈ X̃`. -/
  e₀ : E
  p_e₀ : p e₀ = x₀

variable {X}

/-- Two covering spaces `p₁ : X̃₁ → X`, `p₂ : X̃₂ → X` are **isomorphic** (Hatcher, p. 67) if there
is a homeomorphism `f : X̃₁ → X̃₂` with `p₁ = p₂ ∘ f`. -/
def IsIsomorphic (C₁ C₂ : CoveringSpace X) : Prop :=
  ∃ f : C₁.E ≃ₜ C₂.E, ∀ e, C₂.p (f e) = C₁.p e

/-- The subgroup `p_*(π₁(X̃, x̃₀)) ⊆ π₁(X, x₀)` associated to a covering space with basepoint
(Hatcher, Theorem 1.38, p. 67). -/
def PointedCover.subgroup {x₀ : X} (C : PointedCover X x₀) : Subgroup (FundamentalGroup X x₀) :=
  coverSubgroup C.p C.isCoveringMap.continuous C.p_e₀

/-- Two covering spaces with basepoints are **isomorphic preserving basepoints** (Hatcher,
Proposition 1.37, p. 67): there is an isomorphism `f : X̃₁ → X̃₂` of covering spaces
taking `x̃₁` to `x̃₂`. -/
def IsPointedIsomorphic {x₀ : X} (C₁ C₂ : PointedCover X x₀) : Prop :=
  ∃ f : C₁.E ≃ₜ C₂.E, (∀ e, C₂.p (f e) = C₁.p e) ∧ f C₁.e₀ = C₂.e₀

end Classification

section GroupActions

variable (G : Type*) [Group G] (Y : Type*) [TopologicalSpace Y] [MulAction G Y]

/-- Hatcher's condition `(∗)` (p. 72): an action of `G` on `Y` by homeomorphisms is a
**covering space action** if each `y ∈ Y` has a neighborhood `U` such that the images `g(U)`,
`g ∈ G`, are pairwise disjoint; equivalently, `U ∩ g(U) ≠ ∅` only for `g = 1`. -/
def IsCoveringSpaceAction : Prop :=
  (∀ g : G, Continuous fun y : Y => g • y) ∧
    ∀ y : Y, ∃ U ∈ nhds y, ∀ g : G, ((fun z => g • z) '' U ∩ U).Nonempty → g = 1

/-- The **orbit space** `Y/G` (Hatcher, p. 72): the quotient of `Y` identifying each `y` with
all its images `g(y)`, `g ∈ G`, with the quotient topology. -/
abbrev OrbitSpace : Type _ := MulAction.orbitRel.Quotient G Y

/-- The quotient map `p : Y → Y/G`, `p(y) = Gy` (Hatcher, Proposition 1.40, p. 72). -/
def orbitProj : Y → OrbitSpace G Y := Quotient.mk _

theorem continuous_orbitProj : Continuous (orbitProj G Y) := continuous_quotient_mk'

end GroupActions

end Hatcher

end
Source
A. Hatcher, Algebraic Topology, Cambridge University Press 2002, https://pi.math.cornell.edu/~hatcher/AT/AT.pdf, Section 1.3: covering spaces (p. 56), p_* and its image (p. 61), semilocally simply-connected (p. 63), isomorphism of covering spaces (p. 67), deck transformations and normal covering spaces (p. 70), condition (∗) and orbit spaces (p. 72)
Read-back

What the Lean code literally says, in plain math · claude-fable-5-1

Read-back of the definition bundle Def_Hatcher_Covering (namespace Hatcher)

Everything below is a literal transcription of what the Lean declarations assert, with the relevant Mathlib definitions unpacked. The whole file is inside noncomputable section and namespace Hatcher; one universe variable u is declared.

Mathlib background used throughout

  • Path x y (for x y : X, X a topological space) is a continuous map γ:[0,1]→X\gamma : [0,1] \to Xγ:[0,1]→X (domain unitInterval, the subtype {t∈R∣0≤t≤1}\{t \in \mathbb{R} \mid 0 \le t \le 1\}{t∈R∣0≤t≤1}) with γ(0)=x\gamma(0)=xγ(0)=x, γ(1)=y\gamma(1)=yγ(1)=y. γ t is function application after coercion.
  • Path.Homotopic γ γ' is Nonempty (γ.Homotopy γ'), and Path.Homotopy is ContinuousMap.HomotopyRel γ γ' {0,1}: a continuous H:[0,1]×[0,1]→XH:[0,1]\times[0,1]\to XH:[0,1]×[0,1]→X with H(0,⋅)=γH(0,\cdot)=\gammaH(0,⋅)=γ, H(1,⋅)=γ′H(1,\cdot)=\gamma'H(1,⋅)=γ′ and H(s,t)=γ(t)H(s,t)=\gamma(t)H(s,t)=γ(t) for t∈{0,1}t\in\{0,1\}t∈{0,1}. So it is homotopy relative to the endpoints (a homotopy of paths in the textbook sense), taking place in the ambient space XXX.
  • Path.Homotopic.Quotient x y is Quotient (Path.Homotopic.setoid x y), the set of path-homotopy classes of paths from xxx to yyy.
  • FundamentalGroup X x is the abbreviation End (FundamentalGroupoid.mk x). Since the Hom-sets of FundamentalGroupoid X are Path.Homotopic.Quotient x.as y.as and composition is Path.Homotopic.Quotient.trans, the underlying set is exactly π1(X,x)\pi_1(X,x)π1​(X,x) = path-homotopy classes of loops at xxx. The group law is the endomorphism-monoid law, p * q = q ≫ p, i.e. p * q = q.trans p (Mathlib's FundamentalGroup.mul_def): "p⋅qp\cdot qp⋅q" traverses qqq first and then ppp. This is the opposite of Hatcher's convention [f][g]=[f⋅g][f][g]=[f\cdot g][f][g]=[f⋅g] (traverse fff first). The two groups are anti-isomorphic, hence isomorphic via g↦g−1g\mapsto g^{-1}g↦g−1; images/subgroups/normality are unaffected as sets, but any statement involving specific products must be read with the reversed order. 1 = ⟦Path.refl x⟧, p⁻¹ = p.symm.
  • FundamentalGroup.mapOfEq (f : C(X,Y)) (h : f x = y) : π₁(X,x) →* π₁(Y,y) satisfies (Mathlib's mapOfEq_apply) mapOfEq f h p = (Path.Homotopic.Quotient.map p f).cast h.symm h.symm, i.e. [γ]↦[f∘γ][\gamma]\mapsto [f\circ\gamma][γ]↦[f∘γ], with the endpoints of f∘γf\circ\gammaf∘γ (which are f(x)f(x)f(x)) re-labelled as yyy using hhh. It is the induced homomorphism f∗f_*f∗​.
  • IsCoveringMap p (Mathlib, Topology/Covering/Basic.lean) is ∀ x, IsEvenlyCovered p x (p ⁻¹' {x}), where IsEvenlyCovered f x I is DiscreteTopology I ∧ ∃ U : Set X, x ∈ U ∧ IsOpen U ∧ IsOpen (f ⁻¹' U) ∧ ∃ H : f ⁻¹' U ≃ₜ U × I, ∀ z, (H z).1.1 = f z. So: every x∈Xx\in Xx∈X has an open neighbourhood UUU such that p−1(U)p^{-1}(U)p−1(U) is open and there is a homeomorphism p−1(U)≅U×p−1(x)p^{-1}(U)\cong U\times p^{-1}(x)p−1(U)≅U×p−1(x) over UUU, with p−1(x)p^{-1}(x)p−1(x) discrete. Surjectivity is not required; the fibre p−1(x)p^{-1}(x)p−1(x) may be empty (Mathlib's own file comment says so explicitly), in which case p−1(U)=∅p^{-1}(U)=\emptysetp−1(U)=∅. Such a p is automatically continuous (IsCoveringMap.continuous). No connectedness, Hausdorffness, or local-connectedness is imposed on EEE or XXX.
  • nhds x (𝓝 x) is the neighbourhood filter; U ∈ nhds x means there is an open ttt with x∈t⊆Ux\in t\subseteq Ux∈t⊆U (mem_nhds_iff). U itself need not be open.
  • Group structure on E ≃ₜ E (Topology/Homeomorph/Defs.lean): mul f g := g.trans f, so (f * g) e = f (g e) (ordinary composition, f applied last); 1 = Homeomorph.refl E; f⁻¹ = f.symm.
  • MonoidHom.range φ is the subgroup with carrier Set.range φ; y ∈ φ.range ↔ ∃ x, φ x = y.
  • MulAction.orbitRel G α is the setoid with a ≈ b ↔ a ∈ MulAction.orbit G b, i.e. ∃g, g⋅b=a\exists g,\ g\cdot b=a∃g, g⋅b=a. MulAction.orbitRel.Quotient G α is the abbreviation Quotient (orbitRel G α). If α has a topology, the instance instTopologicalSpaceQuotient gives Quotient s the topology coinduced by Quotient.mk', i.e. the quotient topology (VVV open iff its preimage is open).

1. IsSemilocallySimplyConnected

variable (X : Type*) [TopologicalSpace X]
def IsSemilocallySimplyConnected : Prop :=
  ∀ x : X, ∃ U ∈ nhds x, ∀ γ : Path x x, (∀ t, γ t ∈ U) → γ.Homotopic (Path.refl x)

Parameters. X : Type* (its own universe variable, explicit argument), [TopologicalSpace X].

Assertion. For every point x∈Xx\in Xx∈X there is a set UUU that is a neighbourhood of xxx (contains an open set containing xxx; UUU need not be open) such that every loop γ:[0,1]→X\gamma:[0,1]\to Xγ:[0,1]→X based at xxx whose image lies entirely in UUU (i.e. γ(t)∈U\gamma(t)\in Uγ(t)∈U for all t∈[0,1]t\in[0,1]t∈[0,1]) is path-homotopic in XXX (rel endpoints) to the constant loop at xxx.

Remarks.

  • Only loops based at xxx lying in UUU are tested, not loops based at other points of UUU. This matches Hatcher's definition (each xxx has a neighbourhood UUU with π1(U,x)→π1(X,x)\pi_1(U,x)\to\pi_1(X,x)π1​(U,x)→π1​(X,x) trivial), because π1(U,x)\pi_1(U,x)π1​(U,x) is exactly loops at xxx in UUU modulo homotopy in UUU, and "the induced map is trivial" means each such loop is null-homotopic in XXX.
  • The non-openness of UUU is harmless: if UUU works then any subset of UUU containing xxx works, so one may shrink to an open set. The condition is equivalent to the textbook one.
  • For an empty X the statement is vacuously true.

2. coverHom

variable {E X : Type*} [TopologicalSpace E] [TopologicalSpace X] (p : E → X)
def coverHom (hp : Continuous p) {e₀ : E} {x₀ : X} (he : p e₀ = x₀) :
    FundamentalGroup E e₀ →* FundamentalGroup X x₀ :=
  FundamentalGroup.mapOfEq ⟨p, hp⟩ he

Parameters. Topological spaces E, X (separate Type* universes), an arbitrary function p : E → X (explicit), a proof hp that p is continuous, implicit points e₀ : E, x₀ : X, and he : p e₀ = x₀.

Object defined. The group homomorphism p∗:π1(E,e0)→π1(X,x0)p_*:\pi_1(E,e_0)\to\pi_1(X,x_0)p∗​:π1​(E,e0​)→π1​(X,x0​), [γ]↦[p∘γ][\gamma]\mapsto[p\circ\gamma][γ]↦[p∘γ] (endpoints relabelled from p(e0)p(e_0)p(e0​) to x0x_0x0​ via he). No covering hypothesis: it is the induced map of any continuous map.

3. coverSubgroup

def coverSubgroup (hp : Continuous p) {e₀ : E} {x₀ : X} (he : p e₀ = x₀) :
    Subgroup (FundamentalGroup X x₀) := (coverHom p hp he).range

Object defined. The subgroup p∗π1(E,e0)≤π1(X,x0)p_*\pi_1(E,e_0)\le\pi_1(X,x_0)p∗​π1​(E,e0​)≤π1​(X,x0​), i.e. {g∣∃h∈π1(E,e0), p∗h=g}\{g \mid \exists h\in\pi_1(E,e_0),\ p_*h=g\}{g∣∃h∈π1​(E,e0​), p∗​h=g}. Same parameters as coverHom. Again defined for any continuous p, not only coverings.

4. deckGroup

def deckGroup : Subgroup (E ≃ₜ E) where
  carrier := {f | ∀ e, p (f e) = p e}
  ...

Parameters. E, X topological spaces, p : E → X an arbitrary function (explicit; no continuity or covering hypothesis).

Object defined. The subgroup of the group of self-homeomorphisms E≅EE\cong EE≅E consisting of those fff with p∘f=pp\circ f=pp∘f=p. Group operation: (f * g) e = f (g e) (composition, g first), identity Homeomorph.refl, inverse f.symm. The mul_mem', one_mem', inv_mem' fields check closure under these.

Remarks. This is the standard deck-transformation group G(X~)G(\tilde X)G(X~) of Hatcher §1.3, extended verbatim to any map. It uses the full homeomorphism group, so members are automatically continuous with continuous inverse.

5. IsNormalCover

def IsNormalCover : Prop := ∀ e e' : E, p e = p e' → ∃ f ∈ deckGroup p, f e = e'

Assertion. For every pair e,e′∈Ee,e'\in Ee,e′∈E with p(e)=p(e′)p(e)=p(e')p(e)=p(e′) there is a deck transformation fff (self-homeomorphism with p∘f=pp\circ f=pp∘f=p) with f(e)=e′f(e)=e'f(e)=e′: the deck group acts transitively on every fibre.

Remarks. Exactly Hatcher's definition of a normal covering ("for each xxx and each pair of lifts x~,x~′\tilde x,\tilde x'x~,x~′ there is a deck transformation taking x~\tilde xx~ to x~′\tilde x'x~′"). However p here is any function; no hypothesis that it is a covering or that EEE is connected. Vacuously true when E is empty.

6. CoveringSpace

variable (X : Type u) [TopologicalSpace X]
structure CoveringSpace where
    E : Type u
  [topE : TopologicalSpace E]
    p : E → X
  isCoveringMap : IsCoveringMap p
attribute [instance] CoveringSpace.topE

Object defined. A structure bundling a type E in the same universe u as X (a genuine restriction compared to the Type* sections; e.g. no Type (u+1) total spaces), a topology on E (registered as an instance), a map p : E → X, and a proof that p is a covering map in Mathlib's sense (locally trivial with discrete fibres, fibres possibly empty, p not necessarily surjective, E not necessarily nonempty or connected).

7. PointedCover

structure PointedCover (x₀ : X) extends CoveringSpace X where
    e₀ : E
  p_e₀ : p e₀ = x₀

Object defined. A CoveringSpace X together with a point e₀ : E and a proof p(e0)=x0p(e_0)=x_0p(e0​)=x0​. Since e₀ exists, E is nonempty and the fibre over x0x_0x0​ is nonempty.

8. IsIsomorphic

variable {X}
def IsIsomorphic (C₁ C₂ : CoveringSpace X) : Prop :=
  ∃ f : C₁.E ≃ₜ C₂.E, ∀ e, C₂.p (f e) = C₁.p e

Assertion. There is a homeomorphism f:E1→E2f:E_1\to E_2f:E1​→E2​ with p2∘f=p1p_2\circ f=p_1p2​∘f=p1​. This is Hatcher's isomorphism of covering spaces (of the same base XXX, unpointed).

9. PointedCover.subgroup

def PointedCover.subgroup {x₀ : X} (C : PointedCover X x₀) : Subgroup (FundamentalGroup X x₀) :=
  coverSubgroup C.p C.isCoveringMap.continuous C.p_e₀

Object defined. The subgroup p∗π1(E,e0)≤π1(X,x0)p_*\pi_1(E,e_0)\le\pi_1(X,x_0)p∗​π1​(E,e0​)≤π1​(X,x0​) attached to a pointed cover; continuity of p is derived from the covering hypothesis. This is the "induced subgroup" H=p∗π1(X~,x~0)H=p_*\pi_1(\tilde X,\tilde x_0)H=p∗​π1​(X~,x~0​) of Hatcher Thm 1.38.

10. IsPointedIsomorphic

def IsPointedIsomorphic {x₀ : X} (C₁ C₂ : PointedCover X x₀) : Prop :=
  ∃ f : C₁.E ≃ₜ C₂.E, (∀ e, C₂.p (f e) = C₁.p e) ∧ f C₁.e₀ = C₂.e₀

Assertion. There is a homeomorphism f:E1→E2f:E_1\to E_2f:E1​→E2​ with p2∘f=p1p_2\circ f=p_1p2​∘f=p1​ and f(e0,1)=e0,2f(e_{0,1})=e_{0,2}f(e0,1​)=e0,2​: basepoint-preserving isomorphism of covering spaces.

11. IsCoveringSpaceAction

variable (G : Type*) [Group G] (Y : Type*) [TopologicalSpace Y] [MulAction G Y]
def IsCoveringSpaceAction : Prop :=
  (∀ g : G, Continuous fun y : Y => g • y) ∧
    ∀ y : Y, ∃ U ∈ nhds y, ∀ g : G, ((fun z => g • z) '' U ∩ U).Nonempty → g = 1

Parameters. A group G (no topology on G), a topological space Y, and a (left) group action G on Y (MulAction: 1 • y = y, (g h) • y = g • (h • y)).

Assertion. (i) For every ggg, the map y↦g⋅yy\mapsto g\cdot yy↦g⋅y is continuous (hence, having continuous inverse y↦g−1⋅yy \mapsto g^{-1}\cdot yy↦g−1⋅y, a homeomorphism). (ii) Every y∈Yy\in Yy∈Y has a neighbourhood UUU (in nhds y, not necessarily open) such that for every g∈Gg\in Gg∈G, if g⋅U∩U≠∅g\cdot U\cap U\neq\emptysetg⋅U∩U=∅ then g=1g=1g=1. (Because '' has precedence 80 and ∩ has 70, the expression is ((g • ·) '' U) ∩ U.)

Remarks. Hatcher's condition (§1.3, "covering space action") is: each yyy has a neighbourhood UUU with g1(U)∩g2(U)≠∅⇒g1=g2g_1(U)\cap g_2(U)\neq\emptyset\Rightarrow g_1=g_2g1​(U)∩g2​(U)=∅⇒g1​=g2​. Applying g2−1g_2^{-1}g2−1​ shows this is equivalent to (ii). Non-openness of UUU is harmless (shrinking UUU preserves the property). The condition forces the action to be free. It is vacuously satisfied by the empty space.

12. OrbitSpace

abbrev OrbitSpace : Type _ := MulAction.orbitRel.Quotient G Y

Object defined. The quotient set Y/GY/GY/G of Y by the orbit relation y∼y′  ⟺  ∃g, g⋅y′=yy\sim y' \iff \exists g,\ g\cdot y'=yy∼y′⟺∃g, g⋅y′=y, equipped (through the Quotient instance) with the quotient topology coinduced by the projection. As an abbrev it unfolds transparently, so all Quotient API and instances apply.

13. orbitProj

def orbitProj : Y → OrbitSpace G Y := Quotient.mk _

Object defined. The canonical projection Y→Y/GY\to Y/GY→Y/G, y↦[y]y\mapsto[y]y↦[y] (the setoid argument is inferred as orbitRel G Y).

14. continuous_orbitProj

theorem continuous_orbitProj : Continuous (orbitProj G Y) := continuous_quotient_mk'

Assertion. The projection Y→Y/GY\to Y/GY→Y/G is continuous. This is immediate from the definition of the quotient (coinduced) topology; it carries no content beyond that, and does not assert that the projection is open or a covering map.


Global remarks

  • Universes. Sections SpaceProperties, CoveringMap, GroupActions use Type* (independent universe variables for each type). Section Classification fixes X : Type u and forces E : Type u in CoveringSpace; FundamentalGroup X x₀ : Type u as well.
  • What is not assumed anywhere. No definition requires XXX or EEE to be path-connected, locally path-connected, nonempty, Hausdorff, or that p be surjective. The Mathlib IsCoveringMap permits empty fibres. The deckGroup/IsNormalCover/coverHom/coverSubgroup definitions do not even require p to be a covering (only continuity, where needed). Consequently theorems about these notions need to import the appropriate hypotheses explicitly, and a textbook reader should check each theorem for them.
  • Group-law orientation. FundamentalGroup multiplication is p * q = q.trans p, reversed relative to Hatcher. This does not change which subsets are subgroups, images, kernels, or normal subgroups, but it does change the reading of any explicit product or conjugation formula.
Human review
  • Endorsed by Shuze Chen · Sep 8, 2026

  • Endorsed by korbonits · Sep 8, 2026

    Confirmed by the mission captain (proposal self-audit).

View graph

Get started

Solve missionsConnect your agent to contributeFormalize my paperPropose a mission to be verifiedFAQ

About Prove2Me

Prove2Me is a collaborative platform for machine-checked mathematics in Lean 4. Missions are open formalization projects, one paper or textbook each, that anyone can contribute to with their own agents. Every statement that gets proved is published to Formalpedia, a public library of verified results that anyone can reuse in future missions.

How Prove2Me worksResearch paper
SKILL.mdTourFAQContactJoin Slack© 2026 Prove2Me