Prove2Me
Navigate
DiscoverCollectionsFormalpediaBlogsUsersMomentumMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

Hatcher §1.1: the circle S1S^1S1, the covering p:R→S1p:\mathbb{R}\to S^1p:R→S1, and the loops ωn\omega_nωn​

Definition
Hatcher_Circle

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

algebraic-topologycovering-spacesfundamental-grouphatcher

This bundle fixes the objects of Hatcher's subsection "The Fundamental Group of the Circle" (Section 1.1, pp. 29–30), in the book-wide namespace Hatcher.

The circle S1⊂R2S^1\subset\mathbb{R}^2S1⊂R2 is realised as the unit circle of C\mathbb{C}C (Mathlib's Circle), so the point (cos⁡θ,sin⁡θ)(\cos\theta,\sin\theta)(cosθ,sinθ) is eiθe^{i\theta}eiθ and Hatcher's basepoint (1,0)(1,0)(1,0) is 111.

  1. circleCover is Hatcher's map p:R→S1p:\mathbb{R}\to S^1p:R→S1,
p(s)=(cos⁡2πs, sin⁡2πs)=e2πis,p(s)=(\cos 2\pi s,\ \sin 2\pi s)=e^{2\pi i s},p(s)=(cos2πs, sin2πs)=e2πis,

together with the facts that ppp is continuous, p(0)=1p(0)=1p(0)=1, and p(n)=1p(n)=1p(n)=1 for every integer nnn (so p−1(1)=Zp^{-1}(1)=\mathbb{Z}p−1(1)=Z is visible as the integers).

  1. omegaLoopN n is, for n∈Zn\in\mathbb{Z}n∈Z, Hatcher's loop ωn(s)=(cos⁡2πns, sin⁡2πns)=p(ns)\omega_n(s)=(\cos 2\pi ns,\ \sin 2\pi ns)=p(ns)ωn​(s)=(cos2πns, sin2πns)=p(ns) on I=[0,1]I=[0,1]I=[0,1], packaged as a Mathlib Path from 111 to 111 in S1S^1S1 (continuity and both endpoint equations included).

  2. omegaLoop is Hatcher's loop ω(s)=(cos⁡2πs, sin⁡2πs)=p(s)\omega(s)=(\cos 2\pi s,\ \sin 2\pi s)=p(s)ω(s)=(cos2πs, sin2πs)=p(s), again as a Path from 111 to 111; the lemma omegaLoopN_one records ω1=ω\omega_1=\omegaω1​=ω.

  3. omegaClass is the homotopy class [ω]∈π1(S1,1)[\omega]\in\pi_1(S^1,1)[ω]∈π1​(S1,1), as an element of Mathlib's FundamentalGroup Circle 1.

These are the data in terms of which Theorem 1.7 (π1(S1)\pi_1(S^1)π1​(S1) is infinite cyclic generated by [ω][\omega][ω]) and its supporting lifting lemmas are stated; later missions in the series reuse them.

Formalization Note Hatcher's S1⊂R2S^1\subset\mathbb{R}^2S1⊂R2 is replaced by the unit circle in C\mathbb{C}C, which Mathlib equips with its topology, group structure and the covering map Circle.exp; Hatcher's ppp is Circle.exp precomposed with s↦2πss\mapsto 2\pi ss↦2πs. FundamentalGroup Circle 1 is Mathlib's fundamental group, i.e. the endomorphism group of the point 111 in the fundamental groupoid.

Definition code
import Mathlib

/-!
Hatcher, *Algebraic Topology*, Section 1.1, "The Fundamental Group of the Circle" (pp. 29-30).

The circle `S¹ ⊆ ℝ²` is realised as `Circle`, the unit circle in `ℂ`, so a point
`(cos θ, sin θ) ∈ ℝ²` is `e^{iθ} ∈ ℂ` and the basepoint `(1, 0)` is `1 : Circle`.
-/

namespace Hatcher

open Real

/-- Hatcher's map `p : ℝ → S¹`, `p(s) = (cos 2πs, sin 2πs)`, i.e. `p(s) = e^{2πis}`. -/
noncomputable def circleCover (s : ℝ) : Circle := Circle.exp (2 * π * s)

theorem continuous_circleCover : Continuous circleCover :=
  Circle.exp.continuous.comp (continuous_const.mul continuous_id)

@[simp] theorem circleCover_zero : circleCover 0 = 1 := by
  simp [circleCover]

@[simp] theorem circleCover_intCast (n : ℤ) : circleCover n = 1 := by
  simp [circleCover, Circle.exp_two_pi_mul_int]

/-- Hatcher's loop `ω_n(s) = (cos 2πns, sin 2πns)`, `n ∈ ℤ`, based at `(1, 0)`. -/
noncomputable def omegaLoopN (n : ℤ) : Path (1 : Circle) 1 where
  toFun s := circleCover (n * s)
  continuous_toFun := continuous_circleCover.comp (continuous_const.mul continuous_subtype_val)
  source' := by simp
  target' := by simp

/-- Hatcher's loop `ω(s) = (cos 2πs, sin 2πs)` based at `(1, 0)`; it is `ω_1`. -/
noncomputable def omegaLoop : Path (1 : Circle) 1 where
  toFun s := circleCover s
  continuous_toFun := continuous_circleCover.comp continuous_subtype_val
  source' := by simp
  target' := by simpa using circleCover_intCast 1

@[simp] theorem omegaLoopN_apply (n : ℤ) (s : unitInterval) : omegaLoopN n s = circleCover (n * s) := rfl

@[simp] theorem omegaLoop_apply (s : unitInterval) : omegaLoop s = circleCover s := rfl

theorem omegaLoopN_one : omegaLoopN 1 = omegaLoop := by
  ext s; simp

/-- The homotopy class `[ω] ∈ π₁(S¹, (1, 0))`, as an element of Mathlib's `FundamentalGroup Circle 1`. -/
noncomputable def omegaClass : FundamentalGroup Circle 1 := FundamentalGroup.fromPath ⟦omegaLoop⟧

end Hatcher
Source
A. Hatcher, Algebraic Topology, Cambridge University Press 2002, https://pi.math.cornell.edu/~hatcher/AT/AT.pdf, Section 1.1, pp. 29–30: the map p(s) = (cos 2πs, sin 2πs), the loops ω and ω_n, and the basepoint (1,0) (statement of Theorem 1.7 and the paragraph following it)
Read-back

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

Read-back: Def_Hatcher_Circle bundle

All declarations live in a namespace called Hatcher and depend only on Mathlib. Throughout, the following Mathlib notions are used and are expanded here once so that each paragraph below can refer back to them.

  • The circle. Circle is the type of complex numbers of norm one, S1={z∈C:∥z∥=1}S^1 = \{ z \in \mathbb{C} : \lVert z \rVert = 1 \}S1={z∈C:∥z∥=1} (formally, the metric sphere in C\mathbb{C}C of radius 111 centred at 000), carrying the subspace topology from C\mathbb{C}C and the multiplicative commutative group structure inherited from C\mathbb{C}C; its identity element 111 is the complex number 111.
  • The exponential onto the circle. Circle.exp is the continuous map R→S1\mathbb{R} \to S^1R→S1, t↦eitt \mapsto e^{it}t↦eit (formally the complex number exp⁡(t⋅i)\exp(t \cdot i)exp(t⋅i) together with a proof that it has norm one).
  • The unit interval. unitInterval, written III below, is the subset [0,1]={x∈R:0≤x≤1}[0,1] = \{ x \in \mathbb{R} : 0 \le x \le 1 \}[0,1]={x∈R:0≤x≤1} of the reals, viewed as a topological space with the subspace topology. An element s∈Is \in Is∈I is, when used in a real-number expression, silently replaced by its underlying real number.
  • Paths. For points x,yx, yx,y of a topological space XXX, a Path x y is a continuous map γ:I→X\gamma : I \to Xγ:I→X together with proofs that γ(0)=x\gamma(0) = xγ(0)=x and γ(1)=y\gamma(1) = yγ(1)=y. A path from xxx to xxx is a loop based at xxx.
  • Path homotopy and its quotient. Two paths γ0,γ1\gamma_0, \gamma_1γ0​,γ1​ from xxx to yyy are homotopic (Path.Homotopic) if there exists a continuous map F:I×I→XF : I \times I \to XF:I×I→X with F(0,s)=γ0(s)F(0, s) = \gamma_0(s)F(0,s)=γ0​(s), F(1,s)=γ1(s)F(1, s) = \gamma_1(s)F(1,s)=γ1​(s) for all sss, and F(t,0)=γ0(0)=xF(t, 0) = \gamma_0(0) = xF(t,0)=γ0​(0)=x, F(t,1)=γ0(1)=yF(t, 1) = \gamma_0(1) = yF(t,1)=γ0​(1)=y for all ttt (endpoints fixed throughout). This is an equivalence relation, and Path.Homotopic.Quotient x y is the set of equivalence classes. The bracket ⟦γ⟧\llbracket \gamma \rrbracket[[γ]] (written ⟦γ⟧ in the code) denotes the equivalence class of the path γ\gammaγ in this quotient.
  • Fundamental group. FundamentalGroup X x is defined as the set of endomorphisms of the object xxx in Mathlib's fundamental groupoid of XXX; concretely its underlying set is exactly Path.Homotopic.Quotient x x, the set of homotopy classes of loops based at xxx. Its group structure is: identity === the class of the constant loop at xxx; product p⋅qp \cdot qp⋅q === the class of the concatenation "first traverse qqq, then ppp" (note the order); inverse === the class of the reversed loop. FundamentalGroup.fromPath is the map Path.Homotopic.Quotient x x → FundamentalGroup X x that sends a homotopy class of loops to itself regarded as an element of the fundamental group (it is definitionally the identity; it only changes the type label).

The Lean symbol π here is the real number π\piπ (from the Real namespace, which is opened).


circleCover (definition)

For every real number s∈Rs \in \mathbb{R}s∈R, this defines an element of the circle S1S^1S1 by

circleCover⁡(s)  :=  Circle.exp⁡(2πs)  =  e2πis∈S1.\operatorname{circleCover}(s) \;:=\; \operatorname{Circle.exp}(2 \pi s) \;=\; e^{2 \pi i s} \in S^1 .circleCover(s):=Circle.exp(2πs)=e2πis∈S1.

Here 2πs2 \pi s2πs is the real product 2⋅π⋅s2 \cdot \pi \cdot s2⋅π⋅s and Circle.exp⁡\operatorname{Circle.exp}Circle.exp is the map t↦eitt \mapsto e^{it}t↦eit described above. This is a total function R→S1\mathbb{R} \to S^1R→S1 with no restrictions on sss (it is marked noncomputable, which has no mathematical content).

continuous_circleCover (theorem)

Asserts that the function circleCover⁡:R→S1\operatorname{circleCover} : \mathbb{R} \to S^1circleCover:R→S1, s↦e2πiss \mapsto e^{2\pi i s}s↦e2πis, is continuous, where R\mathbb{R}R has its usual topology and S1S^1S1 has the subspace topology from C\mathbb{C}C. There are no hypotheses.

circleCover_zero (theorem)

Asserts the single equation

circleCover⁡(0)=1,\operatorname{circleCover}(0) = 1 ,circleCover(0)=1,

i.e. e2πi⋅0=1e^{2\pi i \cdot 0} = 1e2πi⋅0=1, where 000 is the real number zero and 111 is the identity element of the group S1S^1S1 (the complex number 111). No hypotheses.

circleCover_intCast (theorem)

For every integer n∈Zn \in \mathbb{Z}n∈Z, asserts

circleCover⁡(n)=1,\operatorname{circleCover}(n) = 1 ,circleCover(n)=1,

where on the left nnn is regarded as a real number (via the canonical inclusion Z↪R\mathbb{Z} \hookrightarrow \mathbb{R}Z↪R), so the claim is e2πin=1e^{2 \pi i n} = 1e2πin=1 in S1S^1S1 for every integer nnn, including n=0n = 0n=0 and negative nnn. No further hypotheses.

omegaLoopN (definition)

For every integer n∈Zn \in \mathbb{Z}n∈Z, this defines a loop in S1S^1S1 based at 111, i.e. an element of Path (1 : Circle) 1, denoted here ωn\omega_nωn​. Its underlying function I→S1I \to S^1I→S1 is

ωn(s)  :=  circleCover⁡(n⋅s)  =  e2πi ns,s∈[0,1],\omega_n(s) \;:=\; \operatorname{circleCover}(n \cdot s) \;=\; e^{2 \pi i\, n s}, \qquad s \in [0,1],ωn​(s):=circleCover(n⋅s)=e2πins,s∈[0,1],

where n⋅sn \cdot sn⋅s is the real product of nnn (cast to R\mathbb{R}R) with the real number underlying s∈Is \in Is∈I. The definition packages, in addition to this function:

  • a proof that s↦e2πinss \mapsto e^{2\pi i n s}s↦e2πins is continuous on III;
  • a proof that ωn(0)=1\omega_n(0) = 1ωn​(0)=1 (the start point is the identity element of S1S^1S1);
  • a proof that ωn(1)=1\omega_n(1) = 1ωn​(1)=1 (the end point is the identity element of S1S^1S1).

Note that n=0n = 0n=0 is allowed, in which case ω0\omega_0ω0​ is the constant loop at 111; negative nnn are also allowed.

omegaLoop (definition)

Defines a loop in S1S^1S1 based at 111 (an element of Path (1 : Circle) 1), denoted here ω\omegaω, whose underlying function is

ω(s)  :=  circleCover⁡(s)  =  e2πis,s∈[0,1],\omega(s) \;:=\; \operatorname{circleCover}(s) \;=\; e^{2 \pi i s}, \qquad s \in [0,1],ω(s):=circleCover(s)=e2πis,s∈[0,1],

where s∈Is \in Is∈I is used via its underlying real number. Packaged with it are proofs that this function is continuous on III, that ω(0)=1\omega(0) = 1ω(0)=1, and that ω(1)=1\omega(1) = 1ω(1)=1 (the last obtained from circleCover_intCast with n=1n = 1n=1). Note that ω\omegaω is defined directly and not as ω1\omega_1ω1​; the relationship between the two is a separate theorem below.

omegaLoopN_apply (theorem)

For every integer n∈Zn \in \mathbb{Z}n∈Z and every point s∈I=[0,1]s \in I = [0,1]s∈I=[0,1], asserts

ωn(s)=circleCover⁡(n⋅s)  (=e2πins),\omega_n(s) = \operatorname{circleCover}(n \cdot s) \;\bigl(= e^{2\pi i n s}\bigr),ωn​(s)=circleCover(n⋅s)(=e2πins),

where ωn\omega_nωn​ is the loop defined by omegaLoopN evaluated at sss. This holds by definition (the proof is rfl); the statement records how the loop evaluates pointwise.

omegaLoop_apply (theorem)

For every point s∈I=[0,1]s \in I = [0,1]s∈I=[0,1], asserts

ω(s)=circleCover⁡(s)  (=e2πis),\omega(s) = \operatorname{circleCover}(s) \;\bigl(= e^{2\pi i s}\bigr),ω(s)=circleCover(s)(=e2πis),

where ω\omegaω is the loop defined by omegaLoop. Again this holds by definition.

omegaLoopN_one (theorem)

Asserts the equality of loops

ω1=ω,\omega_1 = \omega ,ω1​=ω,

i.e. the loop omegaLoopN 1 (with underlying function s↦e2πi⋅(1⋅s)s \mapsto e^{2 \pi i \cdot (1 \cdot s)}s↦e2πi⋅(1⋅s), where 111 is the integer one cast to R\mathbb{R}R) is equal, as an element of Path (1 : Circle) 1, to the loop omegaLoop (with underlying function s↦e2πiss \mapsto e^{2 \pi i s}s↦e2πis). Equality of paths here means equality of the underlying functions I→S1I \to S^1I→S1 at every point s∈Is \in Is∈I (the endpoint proofs carry no data). No hypotheses.

omegaClass (definition)

Defines an element of the fundamental group of S1S^1S1 at the basepoint 111, i.e. of FundamentalGroup Circle 1, by

omegaClass⁡  :=  FundamentalGroup.fromPath⁡(⟦ω⟧),\operatorname{omegaClass} \;:=\; \operatorname{FundamentalGroup.fromPath}\bigl(\llbracket \omega \rrbracket\bigr),omegaClass:=FundamentalGroup.fromPath([[ω]]),

where ⟦ω⟧\llbracket \omega \rrbracket[[ω]] is the homotopy class (relative to the fixed endpoints 0,1∈I0, 1 \in I0,1∈I) of the loop ω:s↦e2πis\omega : s \mapsto e^{2\pi i s}ω:s↦e2πis in the quotient Path.Homotopic.Quotient 1 1, and FundamentalGroup.fromPath⁡\operatorname{FundamentalGroup.fromPath}FundamentalGroup.fromPath re-labels that class as an element of the group FundamentalGroup Circle 1 (whose elements are exactly such classes, with product "concatenate, second factor first", identity the class of the constant loop at 111, and inverse given by reversal). Nothing is asserted about this element (for instance, no claim is made that it generates the group, that it is non-trivial, or that it has infinite order); the declaration only names it.

Human review
  • Endorsed by Shuze Chen · Sep 5, 2026

  • Endorsed by korbonits · Sep 5, 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, with reuse governed by our licensing terms.

How Prove2Me worksResearch paper
SKILL.mdTourFAQContactTerms
© 2026 Prove2Me