A number that refuses to change
Take a cube: corners, edges, faces, and . A tetrahedron: . A pyramid on a square base: . A football stitched from pentagons and hexagons: . Every solid you can think of without a hole through it gives the same answer. Leonhard Euler noticed this in 1750 and wrote to Christian Goldbach about it, remarking that, as far as he knew, nobody had observed it before.
Now take a square picture frame, built from four-sided faces: . A frame with two holes gives . The number is blind to size, shape and the way a solid is cut into faces, but it sees holes. It is the first invariant of topology, the geometry of properties that survive stretching and bending.
The same count answers puzzles that seem to have nothing to do with solids. Why does every football (and every molecule) have exactly twelve pentagons? Why can three houses not each be joined to three utilities by pipes that never cross? Why are there exactly five regular solids? And it leads to one of the great theorems of the 20th century's foundations: every closed surface is a sphere, a many-holed doughnut, or a "one-sided" relative of the projective plane — and , together with one yes/no question, tells you which. Along the way we use graphs, a little Euclidean geometry, and proof by induction.
Count them yourself
Count the vertices, edges and faces of each solid below, and compute . Then open the Surfaces and genus tab: refining the subdivision (splitting an edge, cutting a face with a diagonal) changes , and but never .
Vertices, edges and faces
Solids without holes give 2. What do the frames give?
Drag to turn it. Dashed lines are edges at the back.
Tetrahedron
Count them yourself — turning the solid helps. Click in a box to highlight what you are counting.
| Solid | V | E | F | V − E + F |
|---|---|---|---|---|
| Tetrahedron | ? | ? | ? | ? |
| Cube | ? | ? | ? | ? |
| Octahedron | ? | ? | ? | ? |
| Dodecahedron | ? | ? | ? | ? |
| Icosahedron | ? | ? | ? | ? |
| Triangular prism | ? | ? | ? | ? |
| Square pyramid | ? | ? | ? | ? |
| Picture frame (one hole) | ? | ? | ? | ? |
| Frame with two holes | ? | ? | ? | ? |
Counted 0 of 9. Every solid without holes gives 2; holes change the answer.
Here is why the answer should not depend on the solid. Imagine the polyhedron made of rubber and inflate it into a round ball; its edges become curves drawn on the sphere, dividing it into faces. Cutting a face along a new edge between two of its corners adds one edge and one face: is unchanged. Adding a new vertex in the middle of an edge adds one vertex and one edge: unchanged again. Any two ways of cutting up the same surface can be compared through a common refinement, so they must give the same number. That number is a property of the surface, not of the cutting — its Euler characteristic .
Definitions
Definition— plane graph and faces
A graph consists of finitely many vertices and edges, each edge joining two vertices. A plane graph is a graph drawn in the plane so that edges are curves (for us, polygonal paths) that meet only at shared endpoints. Its faces are the connected regions into which the drawing cuts the plane, including the unbounded outer region. A graph is planar if it can be drawn this way.
Definition— surface
A (closed) surface is a compact Hausdorff space in which every point has a neighbourhood homeomorphic to an open disc. Two spaces are homeomorphic if there is a continuous bijection between them with a continuous inverse — the precise meaning of "the same shape up to stretching and bending, without tearing or gluing". Examples: the sphere , the torus . Non-examples: the closed disc and the Möbius band (points on the edge have only half-disc neighbourhoods; these are surfaces with boundary), and two spheres touching at a point (the touching point has no disc neighbourhood).
Definition— subdivision and Euler characteristic
A subdivision of a surface cuts it into finitely many polygonal faces (each homeomorphic to a closed disc bounded by its edges), meeting along whole edges or at vertices. If it has vertices, edges and faces, its Euler characteristic is
Definition— gluing a polygon
A polygon with edge identifications is described by a word: label the sides of a -gon in order around the boundary with letters, each letter used twice, and write when the side is traversed in the direction of its arrow and when against it. Gluing each pair of sides so the arrows match produces a closed surface; its subdivision has , , and = the number of classes of corners that get glued together.
Definition— orientable, connected sum
A surface is orientable if it contains no Möbius band — equivalently, if a consistent choice of "clockwise" can be made on every face, so that a small turning arrow carried around any loop comes back the same way. The connected sum of two surfaces is formed by removing a small open disc from each and gluing the two boundary circles together.
Examples
Example— The five Platonic solids
A Platonic solid is a convex polyhedron whose faces are congruent regular polygons, with the same number of faces at every vertex. Writing for "-gonal faces, at each vertex":
| Solid | |||||
|---|---|---|---|---|---|
| tetrahedron | 4 | 6 | 4 | 2 | |
| cube | 8 | 12 | 6 | 2 | |
| octahedron | 6 | 12 | 8 | 2 | |
| dodecahedron | 20 | 30 | 12 | 2 | |
| icosahedron | 12 | 30 | 20 | 2 |
Swapping and swaps and : the cube and octahedron are dual (put a vertex in the centre of each face of one, and you get the other), as are the dodecahedron and icosahedron; the tetrahedron is dual to itself.
Example— Four surfaces from one square
Glue the sides of a square in pairs. With the words read anticlockwise from the bottom-left corner:
- (opposite sides, both pairs parallel): all four corners become one vertex. , , , so : the torus.
- (one pair parallel, one pair reversed): again one vertex, , but walking across the reversed pair of sides turns left into right: the Klein bottle, non-orientable.
- (adjacent sides folded together): three vertices, so : the sphere (fold the square like an envelope).
- (both pairs reversed): the corners form two classes, : the real projective plane, non-orientable.
Gluing only one pair, gives a cylinder, and (with a half twist) the Möbius band: , (the glued side and the two free sides), , so .
Example— Non-examples and boundary cases
- The picture frame (a polyhedron with a tunnel) has : Euler's "" is a theorem about solids without holes, not about every polyhedron.
- Two cubes sharing a single vertex: , , , so . This is not a surface (the shared vertex has no disc neighbourhood), which is why no theorem about surfaces predicts it.
Euler's formula and its consequences
Theorem— Theorem (Euler's formula)
Every connected plane graph with vertices, edges and faces satisfies .
Proof
We use two facts about polygonal curves in the plane: (J) a closed polygonal curve without self-intersections separates the plane into exactly two regions, and each edge of the curve borders both (the polygonal Jordan curve theorem, which has an elementary proof); (L) an edge ending at a vertex of degree has the same face on both sides (one can walk around its free end).
Induction on . If , the graph is a single vertex: . Let .
If some vertex has degree , delete it together with its edge. The graph stays connected, and by (L) the number of faces does not change: and each drop by , so is unchanged.
Otherwise every vertex has degree at least . Then the graph contains a cycle: walk along edges without immediately reversing; since there are finitely many vertices, some vertex repeats, and the walk between its two visits is a cycle. Delete one edge of this cycle. The graph stays connected (the rest of the cycle still joins the ends of ). By (J), the two sides of lie in different faces — one inside the cycle, one outside — and deleting merges them into one. So and each drop by , and is unchanged.
In both cases the smaller graph satisfies the formula by induction, hence so does the original.
∎
The proof shows that is unchanged by deleting a "leaf" or a "cycle edge", and these moves reduce any connected graph to a single vertex. In the language of Mathlib, the leaf-deletion half is the statement that a tree with vertices has edges.
Theorem— Corollary (convex polyhedra)
Every convex polyhedron satisfies .
Proof
Choose a face and a point just outside the polyhedron near the middle of , and project the polyhedron from that point onto the plane of (looking through , the whole polyhedron appears inside it — a Schlegel diagram). Convexity makes this a plane graph whose bounded faces are the other faces of the polyhedron and whose outer face corresponds to . It has the same , and , and it is connected, so Euler's formula applies.
∎
Theorem— Theorem (there are exactly five Platonic solids)
If a convex polyhedron has every face a -gon and faces at every vertex (), then is one of , and are as in the table.
Proof
Each edge borders two faces and each face has edges, so ; each edge has two ends and each vertex has edges, so . Substituting and into Euler's formula:
So , i.e. , i.e. . With both factors are at least , so each is at most : , and the only pairs are the five listed. For each, gives , and then , . All five exist (their coordinates are in the computation section).
∎
The same counting gives two famous results.
Theorem— Theorem (K₅ and K₃,₃ are not planar)
A simple planar graph (no loops or multiple edges) with vertices has ; if it has no triangles, . Hence the complete graph and the complete bipartite graph are not planar.
Proof
We may assume the graph is connected (otherwise add edges between components; this only strengthens the inequality to prove). In a plane drawing with , every face is bounded by at least edges (at least if there are no triangles), and each edge borders at most two faces, so (or ). Substituting : , i.e. (respectively ). has , . is bipartite, so has no triangles, and .
∎
The statement is the three utilities puzzle: three houses cannot each be joined to water, gas and electricity by non-crossing pipes in the plane. On a torus they can — a hint that governs graph drawing on other surfaces too.
Theorem— Theorem (twelve pentagons)
If every face of a polyhedron with is a pentagon or a hexagon, and exactly three faces meet at each vertex, then there are exactly pentagons.
Proof
Let there be pentagons and hexagons. Counting edge–face incidences, ; counting edge–vertex incidences, . Then , and .
∎
This is why footballs, the carbon molecule (buckminsterfullerene), geodesic domes and many virus shells all have exactly twelve five-fold points, while the number of hexagons varies.
Theorem— Theorem (Descartes: the total angle defect is 4π)
At a vertex of a polyhedron, the angle defect is minus the sum of the face angles there. For a polyhedron with , the defects add up to ; in general they add up to .
Proof
The angles of an -gon add up to , and each edge borders two faces, so the sides of all faces add up to . Summing all face angles face by face, . The total defect is .
∎
For a cube, each vertex has three right angles, so defect , and . For the picture frame, the outer corners have defect and the inner corners , and they cancel. This "discrete curvature" is the ancestor of the Gauss–Bonnet theorem (see the viewpoints).
Surfaces, invariance and classification
Theorem— Theorem (invariance of the Euler characteristic)
Any two subdivisions of the same surface — or of homeomorphic surfaces — have the same .
Proof sketch. Each of the elementary refinements — a new vertex on an edge (, ), a new edge across a face (, ), a new vertex inside a face joined to a corner (, ) — leaves unchanged, and so does their inverse. The hard part is that any two subdivisions have a common refinement reachable by such moves; for arbitrary (wild) subdivisions this needs care, and the cleanest complete proof uses homology: , where the Betti numbers are ranks of homology groups, which are homeomorphism invariants by construction (see algebraic topology). That every surface has a subdivision at all is Tibor Radó's theorem (1925).
Theorem— Proposition (connected sums)
.
Proof
Choose subdivisions in which and each have an -gon face, and form the connected sum by removing these two faces and gluing their boundary polygons edge to edge. The vertices and edges of the two boundaries are identified in pairs, and two faces are lost: , , . Subtracting, .
∎
So the connected sum of tori, , has , and the connected sum of projective planes, , has . In word form, is (a -gon) and is (a -gon). For example, the double torus is an octagon (writing capitals for inverses), with all eight corners glued to one vertex: .
Theorem— Theorem (classification of closed surfaces)
Every closed connected surface is homeomorphic to exactly one of: the sphere ; a connected sum of tori (, orientable); a connected sum of projective planes (, non-orientable). In particular, two closed connected surfaces are homeomorphic if and only if they have the same Euler characteristic and are both orientable or both non-orientable.
Proof sketch. (1) Triangulate the surface (Radó). (2) Cut it open along edges of a spanning tree of the dual graph, obtaining a single polygon with paired sides, described by a word. (3) Simplify the word by cut-and-paste moves that do not change the surface: cancel adjacent pairs ; bring each twisted pair together as ; arrange the remaining pairs into commutators ; reduce to a word with a single vertex class. (4) Use the relation (Walther von Dyck, 1888) to remove tori when twisted pairs are present. The resulting normal forms are the list above, and they are distinguished by and orientability, which are invariants. Complete proofs: Massey (1967, ch. 1), Armstrong (1983, ch. 7), Gallier and Xu (2013); Conway's elegant "ZIP proof" is written up by Francis and Weeks (1999).
Example— Identifying surfaces from words
- (a hexagon, capitals for inverses): orientable (each letter once each way). Chasing corners gives vertex classes, so : a torus.
- : non-orientable, one vertex class, : , Dyck's surface.
- : ; non-orientable with . By the classification it is — Dyck's theorem, recovered by counting.
- : non-orientable, : the Klein bottle, which is therefore .
The Klein bottle cannot be embedded in — a closed surface embedded in separates space into an inside and an outside and is therefore orientable — so its familiar glass models pass through themselves. In there is room: use the fourth coordinate to lift the tube where it would cross, and the self-intersection disappears. The same holds for every non-orientable closed surface.
What Lean checks
Mathlib has graphs (SimpleGraph), trees and spanning trees, but not yet plane drawings or their faces, so Euler's formula itself is not formalised here. What is formalised is all the counting that follows from it, with Euler's formula taken as a hypothesis (V + F = E + 2, in natural numbers to avoid subtraction). The definitions:
/-- The numbers of vertices, edges and faces of a surface divided into polygons. -/
structure Cells where
/-- number of vertices -/
V : ℕ
/-- number of edges -/
E : ℕ
/-- number of faces -/
F : ℕ/-- The Euler characteristic `χ = V - E + F`, an integer (it can be negative). -/
def euler (c : Cells) : ℤ := (c.V : ℤ) - c.E + c.F/-- The tetrahedron, cube and icosahedron have `χ = 2`; the picture-frame torus
(`V = 16, E = 32, F = 16`) has `χ = 0`. -/
theorem euler_examples :
euler ⟨4, 6, 4⟩ = 2 ∧ euler ⟨8, 12, 6⟩ = 2 ∧ euler ⟨12, 30, 20⟩ = 2 ∧
euler ⟨16, 32, 16⟩ = 0 := by
refine ⟨?_, ?_, ?_, ?_⟩ <;> rflThe Platonic solids: the proof multiplies Euler's formula by , bounds by nonlinear arithmetic (nlinarith), and then checks the remaining nine cases (interval_cases, omega) — exactly the human proof, including the values of , , :
/-- **There are exactly five Platonic solids.** Suppose a polyhedron with `V - E + F = 2` has
every face a `p`-gon and `q` faces at every vertex, with `p, q ≥ 3`. Counting edge–face and
edge–vertex incidences gives `p F = 2E` and `q V = 2E`. Multiplying Euler's formula by `p q`
gives `E (2p + 2q - pq) = 2pq > 0`, so `(p - 2)(q - 2) < 4`; hence `p, q ≤ 5`, and checking
the remaining cases leaves exactly the tetrahedron, octahedron, cube, icosahedron and
dodecahedron, with their numbers of vertices, edges and faces. -/
theorem platonic_solids (p q V E F : ℕ) (hp : 3 ≤ p) (hq : 3 ≤ q) (hF : p * F = 2 * E)
(hV : q * V = 2 * E) (hEuler : V + F = E + 2) :
(p = 3 ∧ q = 3 ∧ V = 4 ∧ E = 6 ∧ F = 4) ∨
(p = 3 ∧ q = 4 ∧ V = 6 ∧ E = 12 ∧ F = 8) ∨
(p = 4 ∧ q = 3 ∧ V = 8 ∧ E = 12 ∧ F = 6) ∨
(p = 3 ∧ q = 5 ∧ V = 12 ∧ E = 30 ∧ F = 20) ∨
(p = 5 ∧ q = 3 ∧ V = 20 ∧ E = 30 ∧ F = 12) := by
-- Euler's formula times `p q`: `2E (p + q) = E p q + 2 p q`.
have key : 2 * E * (p + q) = E * (p * q) + 2 * (p * q) :=
calc 2 * E * (p + q) = p * (q * V) + q * (p * F) := by rw [hV, hF]; ring
_ = p * q * (V + F) := by ring
_ = p * q * (E + 2) := by rw [hEuler]
_ = E * (p * q) + 2 * (p * q) := by ring
-- So `(p - 2)(q - 2) < 4`, which bounds `p` and `q`.
have hp5 : p ≤ 5 := by
by_contra hcon
push Not at hcon
have : 2 * (p + q) ≤ p * q := by nlinarith
nlinarith [key, this]
have hq5 : q ≤ 5 := by
by_contra hcon
push Not at hcon
have : 2 * (p + q) ≤ p * q := by nlinarith
nlinarith [key, this]
interval_cases p <;> interval_cases q <;> omegaThe other consequences are linear arithmetic once the incidence counts are written down:
/-- **The football theorem.** A polyhedron whose faces are `P` pentagons and `H` hexagons,
with exactly three faces at each vertex, has exactly `12` pentagons — however many hexagons it
has (football: `H = 20`; the C₆₀ molecule; geodesic domes; many virus shells). From
`5P + 6H = 2E`, `3V = 2E` and `V - E + (P + H) = 2`: multiply Euler's formula by `6`. -/
theorem twelve_pentagons (P H V E : ℕ) (hfaces : 5 * P + 6 * H = 2 * E) (hvert : 3 * V = 2 * E)
(hEuler : V + (P + H) = E + 2) : P = 12 := by
omega/-- **A simple plane graph has at most `3V - 6` edges.** In a drawing with `V - E + F = 2`
where every face is bounded by at least `3` edges, counting edge–face incidences gives
`3F ≤ 2E`; substituting into Euler's formula gives `E + 6 ≤ 3V`. -/
theorem edge_bound (V E F : ℕ) (hEuler : V + F = E + 2) (hfaces : 3 * F ≤ 2 * E) :
E + 6 ≤ 3 * V := by
omega/-- **`K₅` is not planar.** It has `V = 5` and `E = 10`, but `edge_bound` would need
`10 + 6 ≤ 15`. So no number of faces `F` is compatible with Euler's formula and `3F ≤ 2E`. -/
theorem k5_not_planar : ¬ ∃ F : ℕ, 5 + F = 10 + 2 ∧ 3 * F ≤ 2 * 10 := by
rintro ⟨F, h1, h2⟩
have := edge_bound 5 10 F h1 h2
omega/-- **`K₃,₃` is not planar** (the three-utilities puzzle). It has `V = 6`, `E = 9`, and no
triangles (it is bipartite), so every face would have at least `4` edges: `4F ≤ 2E = 18`.
Euler's formula forces `F = 5`, and `20 > 18`. -/
theorem k33_not_planar : ¬ ∃ F : ℕ, 6 + F = 9 + 2 ∧ 4 * F ≤ 2 * 9 := by
rintro ⟨F, h1, h2⟩
omega/-- **Descartes's theorem on angle defects** (the discrete Gauss–Bonnet theorem). On a
polyhedron with `V` vertices, `E` edges and faces with `n₁, …, n_F` sides, the angles of an
`n`-gon add up to `(n - 2) π`, and `∑ nᵢ = 2E`. The *total angle defect* — `2π` per vertex
minus all the face angles — is then `2π (V - E + F)`; for a sphere-like polyhedron, `4π`. -/
theorem descartes_defect {F : ℕ} (V E : ℕ) (sides : Fin F → ℕ)
(hsides : ∑ i, sides i = 2 * E) :
2 * Real.pi * V - ∑ i, ((sides i : ℝ) - 2) * Real.pi =
2 * Real.pi * ((V : ℝ) - E + F) := by
have hsum : ∑ i, ((sides i : ℝ) - 2) * Real.pi = (2 * E - 2 * F) * Real.pi := by
rw [← Finset.sum_mul, Finset.sum_sub_distrib]
have h : ∑ i, (sides i : ℝ) = 2 * E := by exact_mod_cast hsides
rw [h]
simp
ring
rw [hsum]
ringThe connected-sum formula and the invariance of under the elementary refinements (but not the existence of common refinements):
/-- The cell counts of a **connected sum**: remove an `n`-gon face from each surface and glue
the two boundary polygons together. The `n` vertices and `n` edges of the two boundaries are
identified in pairs, and two faces disappear. -/
def connectedSum (c₁ c₂ : Cells) (n : ℕ) : Cells :=
⟨c₁.V + c₂.V - n, c₁.E + c₂.E - n, c₁.F + c₂.F - 2⟩/-- **`χ(M # N) = χ(M) + χ(N) - 2`.** The `n` lost vertices and `n` lost edges cancel and only
the two lost faces count. (Geometrically each surface must have an `n`-gon face to remove; the
hypotheses here only ensure that the natural-number subtractions in `connectedSum` do not
truncate.) Consequently the connected sum of `g` tori has `χ = 2 - 2g`, and of `k` projective
planes `χ = 2 - k`. -/
theorem euler_connected_sum (c₁ c₂ : Cells) (n : ℕ) (hV : n ≤ c₁.V) (hE : n ≤ c₁.E)
(hF₁ : 1 ≤ c₁.F) (hF₂ : 1 ≤ c₂.F) :
euler (connectedSum c₁ c₂ n) = euler c₁ + euler c₂ - 2 := by
unfold euler connectedSum
simp only
omega/-- **Refining a subdivision does not change `χ`.** The three elementary refinements — put a
new vertex in the middle of an edge (`V + 1`, `E + 1`), cut a face by a diagonal (`E + 1`,
`F + 1`), or put a new vertex inside a face joined to one corner (`V + 1`, `E + 1`) — each
leave `V - E + F` unchanged. (That any two subdivisions have a common refinement is the hard
part of the invariance theorem, and is not formalised here.) -/
theorem subdivision_invariant (c : Cells) :
euler ⟨c.V + 1, c.E + 1, c.F⟩ = euler c ∧ euler ⟨c.V, c.E + 1, c.F + 1⟩ = euler c := by
unfold euler
constructor <;> push_cast <;> ringFinally, Mathlib's graph theory supplies the base case of the proof of Euler's formula (a tree has , so with its single face ) and the inequality for connected graphs:
/-- **A finite tree has `E = V - 1`.** Drawn in the plane, a tree has one face, so it satisfies
`V - E + F = 2`: this is the base case of the proof of Euler's formula by deleting edges of
cycles. This is Mathlib's `SimpleGraph.IsTree.card_edgeFinset`. -/
theorem tree_edges {W : Type*} [Fintype W] (G : SimpleGraph W) [Fintype G.edgeSet]
(hG : G.IsTree) : G.edgeFinset.card + 1 = Fintype.card W :=
hG.card_edgeFinset/-- **A connected graph has `V ≤ E + 1`**, i.e. `E - V + 2 ≥ 1`: a plane drawing of a connected
graph has at least one face, as Euler's formula predicts. Mathlib proves it by choosing a
spanning tree: `SimpleGraph.Connected.card_vert_le_card_edgeSet_add_one`. -/
theorem connected_edges {W : Type*} (G : SimpleGraph W) (hG : G.Connected) :
Nat.card W ≤ Nat.card G.edgeSet + 1 :=
hG.card_vert_le_card_edgeSet_add_oneHonest summary. Formalised: the combinatorial consequences of Euler's formula, Descartes's theorem as an identity about angle sums, the connected-sum formula, the refinement moves, and the tree case. Not formalised: plane drawings, faces and the Jordan curve theorem (Mathlib has the topological Jordan curve theorem only in special forms), surfaces as topological spaces with subdivisions, the topological invariance of , and the classification theorem.
Counting with a computer
The first experiment builds the five Platonic solids from explicit coordinates — for instance the icosahedron's twelve vertices are the cyclic permutations of with the golden ratio. It finds the edges as the pairs of vertices at minimal distance and the faces as the shortest cycles of the edge graph, checks Euler's formula, and adds up Descartes's angle defects from the actual angles. It ends with the picture frame, whose defects cancel.
"""The five Platonic solids from coordinates: counting V, E, F and angle defects.
Part 1 lists the solutions of the inequality (p - 2)(q - 2) < 4 with p, q >= 3,
which Euler's formula forces on a polyhedron with p-gonal faces and q faces at
each vertex, and computes V, E, F from E = 2pq / (2p + 2q - pq). Part 2 starts
from explicit vertex coordinates of the five solids, finds the edges as the
pairs of vertices at minimal distance, finds the faces as the shortest cycles
of the edge graph, and checks V - E + F = 2. It also adds up Descartes's angle
defects (2 pi minus the face angles at each vertex) and finds 4 pi = 2 pi chi;
for a square picture frame, a torus, the defects cancel to 0. Exact counting
on explicit polyhedra, with floating point only in distances and angles.
"""
import itertools
import math
PHI = (1 + math.sqrt(5)) / 2
def schlafli_solutions(limit=20):
"""All (p, q, V, E, F) with 3 <= p, q <= limit and (p-2)(q-2) < 4."""
out = []
for p, q in itertools.product(range(3, limit + 1), repeat=2):
d = 2 * p + 2 * q - p * q
if d > 0:
e = 2 * p * q // d
out.append((p, q, 2 * e // q, e, 2 * e // p))
return out
def cyclic(points):
"""Close a list of points under cyclic permutation of coordinates."""
out = set()
for x, y, z in points:
out |= {(x, y, z), (y, z, x), (z, x, y)}
return sorted(out)
def signs(*coords):
"""All sign combinations of the non-zero coordinates."""
choices = [(c, -c) if c else (0.0,) for c in coords]
return list(itertools.product(*choices))
SOLIDS = {
"tetrahedron": [(1, 1, 1), (1, -1, -1), (-1, 1, -1), (-1, -1, 1)],
"cube": signs(1, 1, 1),
"octahedron": cyclic(signs(1, 0, 0)),
"dodecahedron": signs(1, 1, 1) + cyclic(signs(0, 1 / PHI, PHI)),
"icosahedron": cyclic(signs(0, 1, PHI)),
}
def edges(points):
"""Pairs of vertices at the minimal distance."""
pairs = list(itertools.combinations(range(len(points)), 2))
d = {pr: math.dist(points[pr[0]], points[pr[1]]) for pr in pairs}
m = min(d.values())
return [pr for pr in pairs if abs(d[pr] - m) < 1e-9]
def cycles(n, edge_list, k):
"""All k-cycles (as vertex tuples), each listed once."""
adj = {v: set() for v in range(n)}
for a, b in edge_list:
adj[a].add(b)
adj[b].add(a)
found = []
def extend(path):
if len(path) == k:
if path[0] in adj[path[-1]] and path[1] < path[-1]:
found.append(tuple(path))
return
for w in sorted(adj[path[-1]]):
if w > path[0] and w not in path:
extend(path + [w])
for start in range(n):
extend([start])
return found
def faces(n, edge_list):
"""The shortest cycles of the edge graph (the faces of a Platonic solid)."""
for k in range(3, 7):
found = cycles(n, edge_list, k)
if found:
return found
return []
def angle(a, o, b):
"""The angle at o between the segments oa and ob."""
u = [x - y for x, y in zip(a, o)]
v = [x - y for x, y in zip(b, o)]
c = sum(x * y for x, y in zip(u, v)) / (math.hypot(*u) * math.hypot(*v))
return math.acos(max(-1.0, min(1.0, c)))
def total_defect(points, face_list):
"""Sum over vertices of 2 pi minus the face angles there."""
angle_sum = [0.0] * len(points)
for face in face_list:
k = len(face)
for i in range(k):
a, o, b = face[i - 1], face[i], face[(i + 1) % k]
angle_sum[o] += angle(points[a], points[o], points[b])
return sum(2 * math.pi - s for s in angle_sum)
def picture_frame():
"""A square picture frame (a torus): its 16 vertices and 16 quad faces."""
ring = [(3, 3), (-3, 3), (-3, -3), (3, -3), (1, 1), (-1, 1), (-1, -1),
(1, -1)]
points = [(x, y, z) for z in (1, -1) for x, y in ring]
fs = []
for k in range(4):
o, o1, i, i1 = k, (k + 1) % 4, 4 + k, 4 + (k + 1) % 4
fs += [(o, o1, i1, i), (o + 8, o1 + 8, i1 + 8, i + 8),
(o, o1, o1 + 8, o + 8), (i, i1, i1 + 8, i + 8)]
return points, fs
def edges_of_faces(face_list):
"""The distinct edges of a list of polygonal faces."""
return {tuple(sorted((f[i - 1], f[i]))) for f in face_list
for i in range(len(f))}
def main():
print("Solutions of (p - 2)(q - 2) < 4 with 3 <= p, q <= 20:")
for p, q, v, e, f in schlafli_solutions():
print(f" {{{p},{q}}}: V = {v:>2}, E = {e:>2}, F = {f:>2}")
print()
print("From coordinates (edges = closest pairs, faces = shortest cycles):")
print(f" {'solid':<13}{'V':>3}{'E':>4}{'F':>4}{'p':>3}{'q':>3}"
f"{'V-E+F':>7}{'defect/pi':>11}")
for solid, pts in SOLIDS.items():
es = edges(pts)
v, e = len(pts), len(es)
fs = faces(v, es)
f, p, q = len(fs), len(fs[0]), 2 * e // v
d = total_defect(pts, fs) / math.pi
print(f" {solid:<13}{v:>3}{e:>4}{f:>4}{p:>3}{q:>3}{v - e + f:>7}"
f"{d:>11.6f}")
pts, fs = picture_frame()
v, e, f = len(pts), len(edges_of_faces(fs)), len(fs)
d = total_defect(pts, fs) / math.pi
print(f" {'frame torus':<13}{v:>3}{e:>4}{f:>4}{4:>3}{'-':>3}{v - e + f:>7}"
f"{round(d, 6) + 0.0:>11.6f}")
print(" The torus has chi = 0, and its angle defects cancel: +pi/2 at each")
print(" outer corner, -pi/2 at each inner corner. Total defect = 2 pi chi.")
print()
print("Epistemic status: part 1 is an exhaustive search (the bound p, q <= 5")
print("is proved in the lesson); part 2 counts six explicit polyhedra exactly")
print("(the frame's faces are listed by hand), with floating-point angles, so")
print("the defect sums are numerical. Six examples are evidence for Euler's")
print("and Descartes's theorems, not proofs.")
if __name__ == "__main__":
main()The second experiment turns words into surfaces: it chases corners to find , computes and orientability, and names the result by the classification theorem. Then it does something no hand could: it glues the sides of a -gon in every orientable way (there are of them) and sorts the resulting surfaces by genus.
"""Surfaces from gluing the sides of a polygon: chi, orientability, and a census.
A word such as "abAB" describes a polygon whose sides, read in order, are
glued in pairs: a lower-case letter is a side traversed forwards, the matching
capital letter the partner side traversed backwards. The program finds the
vertex classes after gluing (V), counts edges (E) and faces (F = 1), computes
chi = V - E + F, decides orientability (a surface word is orientable exactly
when every letter occurs once forwards and once backwards), and names the
surface using the classification theorem. Then it glues the sides of a 2n-gon
in every orientable way and counts the results by genus; the genus-0 counts
are the Catalan numbers. Exact and exhaustive, but only for finitely many n.
"""
import itertools
from math import comb
def sides(word):
"""List of (letter, +1/-1) for a word like 'abAB'."""
return [(ch.lower(), 1 if ch.islower() else -1) for ch in word]
def vertex_count(word):
"""Number of vertex classes after gluing the sides of the polygon.
Corner i sits at the start of side i. Gluing side i to its partner j
identifies the start and end of side i with the corresponding ends of
side j (swapped when the two sides run in the same direction).
"""
s = sides(word)
n = len(s)
parent = list(range(n))
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
def union(x, y):
parent[find(x)] = find(y)
positions = {}
for i, (letter, _) in enumerate(s):
positions.setdefault(letter, []).append(i)
for letter, (i, j) in positions.items():
tail_i, head_i = (i, (i + 1) % n)
tail_j, head_j = (j, (j + 1) % n)
if s[i][1] == -1:
tail_i, head_i = head_i, tail_i
if s[j][1] == -1:
tail_j, head_j = head_j, tail_j
union(tail_i, tail_j)
union(head_i, head_j)
return len({find(x) for x in range(n)})
def is_orientable(word):
"""Each letter appears once with each exponent."""
s = sides(word)
return all(sorted(e for l, e in s if l == letter) == [-1, 1]
for letter in {l for l, _ in s})
def euler_characteristic(word):
"""chi = V - E + F for the one-polygon surface given by the word."""
return vertex_count(word) - len(word) // 2 + 1
def name(chi, orientable):
"""Name a closed connected surface by the classification theorem."""
if orientable:
g = (2 - chi) // 2
return {0: "sphere", 1: "torus"}.get(g, f"orientable, genus {g}")
k = 2 - chi
return {1: "projective plane", 2: "Klein bottle"}.get(
k, f"sum of {k} projective planes")
def pairings(items):
"""All perfect matchings of a list of even length."""
if not items:
yield []
return
first, rest = items[0], items[1:]
for k in range(len(rest)):
for m in pairings(rest[:k] + rest[k + 1:]):
yield [(first, rest[k])] + m
def genus_census(n):
"""{genus: count} over all orientable gluings of a 2n-gon."""
counts = {}
letters = "abcdefghij"
for matching in pairings(list(range(2 * n))):
word = [""] * (2 * n)
for k, (i, j) in enumerate(matching):
word[i], word[j] = letters[k], letters[k].upper()
w = "".join(word)
g = (2 - euler_characteristic(w)) // 2
counts[g] = counts.get(g, 0) + 1
return counts
def catalan(n):
"""The n-th Catalan number."""
return comb(2 * n, n) // (n + 1)
def main():
examples = ["aA", "abAB", "abAb", "abab", "aabb", "abcABC",
"abABcdCD", "abABcc", "aabbcc"]
print(f"{'word':<10}{'V':>3}{'E':>3}{'F':>3}{'chi':>5} orientable surface")
for w in examples:
v, e = vertex_count(w), len(w) // 2
chi = v - e + 1
o = is_orientable(w)
print(f"{w:<10}{v:>3}{e:>3}{1:>3}{chi:>5} {str(o):<10} {name(chi, o)}")
print("Note: abABcc (torus # projective plane) has the same chi and")
print("orientability as aabbcc, so by classification they are the same.")
print()
print("All orientable gluings of a 2n-gon, counted by genus:")
for n in range(1, 6):
counts = genus_census(n)
total = sum(counts.values())
row = ", ".join(f"g{g}: {c}" for g, c in sorted(counts.items()))
print(f" n = {n}: {total:>3} gluings; {row};"
f" Catalan({n}) = {catalan(n)}")
print()
print("Epistemic status: exact and exhaustive for the words and the n shown.")
print("That the genus-0 count is always Catalan (and the Harer-Zagier")
print("formula for higher genus) is a theorem; this is evidence for n <= 5.")
if __name__ == "__main__":
main()The genus- counts are the Catalan numbers: a gluing gives a sphere exactly when the pairing of sides is "non-crossing", like a correct arrangement of brackets. The full table is given by the Harer–Zagier formula (1986), which arose in the study of moduli spaces of curves and of random matrices. The experiment checks only; the theorem covers all .
Explore: a flatlander on a glued square
Walk the flatlander across the sides of the square. On the torus it always comes back the same way round. On the Klein bottle and the projective plane, crossing a reversed pair of sides brings it back mirror-reversed — its flag changes hands. That is non-orientability, seen from inside the surface. The tiling view shows the torus and Klein bottle unrolled into the plane.
Surfaces from a square
Which surfaces turn the flatlander into its mirror image? Compare the χ shown for each with the corner count in the lesson.
Keys: ↑ forward, ↓ back, ← and → turn, Space walks or stops. You can also drag it.
- Orientable
- No
- Euler characteristic
- χ = 0
Gluing turns the 4 corners into V = 1, the 4 sides into E = 2 and the square into F = 1: V − E + F = 1 − 2 + 1 = 0
Same way round as at the start.
Sides crossed so far: 0
Top and bottom are glued as on the torus, but the left and right sides are glued with opposite arrows. Walk through them and you come back mirrored. A surface on which a walk can mirror you is called non-orientable. The Klein bottle cannot sit in ordinary 3D space without passing through itself.
Unrolled: copies of the square tile the plane
For the Klein bottle, alternate columns are flipped — the glide reflection of transformation geometry.
Keys: ↑ forward, ↓ back, ← and → turn, Space walks or stops. You can also drag it.
- Orientable
- Yes
- Euler characteristic
- χ = 0
Gluing turns the 4 corners into V = 1, the 4 sides into E = 2 and the square into F = 1: V − E + F = 1 − 2 + 1 = 0
Same way round as at the start.
Sides crossed so far: 0
Opposite sides are glued with arrows pointing the same way. Walk off the right side and you come back on the left, the same way round. However it walks, the flatlander is never mirrored: the torus is orientable.
Copies of the square tile the plane, and the trail runs on smoothly from copy to copy. This plane is the universal cover of the torus.
Exercises
1. Surfaces, polyhedra and the Euler characteristic
Warm-upHumanA convex polyhedron has edges and faces. How many vertices does it have?
2. Surfaces, polyhedra and the Euler characteristic
Warm-upHumanA football is stitched from pentagons and hexagons, with three faces meeting at every vertex. How many vertices does it have?
3. Surfaces, polyhedra and the Euler characteristic
CoreHumanA plane graph consists of three separate triangles, drawn side by side without touching. Compute (remember the outer face).
4. Surfaces, polyhedra and the Euler characteristic
CoreHumanGlue the sides of an octagon according to the word . All eight corners turn out to be glued to a single vertex. The surface is orientable. What is its genus ?
5. Surfaces, polyhedra and the Euler characteristic
CoreHumanWhich of these closed surfaces are orientable? (Choose all that apply.)
6. Surfaces, polyhedra and the Euler characteristic
CoreHumanIn the proof that there are only five Platonic solids we reach . Why does this force ?
7. Surfaces, polyhedra and the Euler characteristic
CoreFormalIn the Lean theorem platonic_solids, which hypothesis encodes every face is a -gon (with faces and edges)?
8. Surfaces, polyhedra and the Euler characteristic
StretchHumanThe hexagon word describes the connected sum of a torus and a projective plane. By the classification theorem, which surface is it?
9. Surfaces, polyhedra and the Euler characteristic
StretchComputationalWrite euler_char(word) for a polygon word such as 'abAB' (lower case: side traversed along its arrow; upper case: against it; each letter used twice). Return , where is the number of corner classes after gluing. Corner is the start of side ; a side running along its arrow goes from corner to corner (mod the number of sides), one running against it goes the other way, and gluing two sides identifies their tails and their heads.
Common misconceptions
Misconception
"Topology ignores all structure." Topology forgets distances and angles, but it keeps exactly the properties preserved by continuous maps with continuous inverses — connectedness, compactness, orientability, the number of holes, the Euler characteristic. These are rigid: no amount of stretching changes . A coffee mug and a doughnut are the same to a topologist; a sphere and a doughnut are not.
Misconception
"A Klein bottle must intersect itself." Every picture or glass model of it in does, because no closed non-orientable surface embeds in . But the Klein bottle itself is a perfectly good surface (a square with glued sides), and it embeds in , where the extra dimension lets the tube pass "around" itself.
Misconception
"Euler's formula holds for every polyhedron." It holds for polyhedra that are topologically spheres — for example all convex ones. A polyhedron with a tunnel through it, like the picture frame, has , and with tunnels, . (Simon Lhuilier pointed this out in 1813; the history of such "exceptions" is the subject of Lakatos's Proofs and Refutations.)
Misconception
"The Euler characteristic alone determines the surface." The torus and the Klein bottle both have . One also needs orientability — and then, by the classification theorem, the pair (χ, orientability) is a complete invariant for closed connected surfaces.
Misconception
"The Möbius band is a one-sided closed surface." It has a boundary circle, so it is a surface with boundary. Gluing a disc to its boundary closes it up into the projective plane: .
Many ways of seeing
Topology— Homology, vector fields and the hairy ball
In algebraic topology, , where counts connected pieces, independent loops that do not bound, and closed two-dimensional pieces (for a closed orientable surface and ). This explains the invariance at once. A deeper link: by the Poincaré–Hopf theorem, for any continuous tangent vector field on a closed surface with finitely many zeros, the sum of the indices of the zeros equals . Since , every tangent vector field on the sphere vanishes somewhere — the hairy ball theorem: you cannot comb a hairy ball flat, and at every moment there is a point on Earth where the horizontal wind velocity is zero. The torus, with , has nowhere-vanishing fields (flow around the tube). See algebraic topology.
Geometry— Gauss–Bonnet: curvature knows the topology
Descartes's theorem has a smooth version, the Gauss–Bonnet theorem: for a closed surface with a Riemannian metric, , where is the Gaussian curvature. However you dent a sphere, its total curvature stays ; any metric on a torus has as much negative as positive curvature. Combined with the uniformisation theorem, this sorts surfaces geometrically: those with (sphere, projective plane) carry metrics of constant curvature , those with (torus, Klein bottle) flat metrics — the square with glued sides — and all the others hyperbolic metrics of curvature , built from polygons in the hyperbolic plane. For curvature , Gauss–Bonnet gives the area: , so a genus- surface has area . See Riemannian geometry.
Combinatorics— Maps, colourings and counting gluings
Euler's formula is the basic tool of topological graph theory. It shows that every planar graph has a vertex of degree at most (since forces average degree below ), which gives a short proof that planar maps can be coloured with colours, and with more work ; the four colour theorem (Appel and Haken, 1976) needed a computer. On other surfaces the answer is governed by : Heawood's bound, proved sharp by Ringel and Youngs (1968), says maps on a closed surface with , other than the Klein bottle, need at most colours — on the torus. And counting gluings of polygons, as in the computation section, leads to the Catalan numbers and the Harer–Zagier formula. See graph theory.
Algebra— The word is a group presentation
The word of a polygon gluing is also a presentation of the fundamental group: the torus has , the projective plane has , and has the surface group . Abelianising gives the first homology group : for and for , which recovers and orientability algebraically. The Euler characteristic also behaves like a "size": it is multiplicative for coverings (an -sheeted cover has multiplied by , so the sphere double covers and ) and for products. See the fundamental group.
Physics— Twelve defects: molecules, viruses and wind
Nature obeys the twelve-pentagon theorem. Buckminsterfullerene (discovered in 1985 by Kroto, Curl and Smalley) is a football of carbon atoms with pentagons and hexagons, and every closed fullerene cage of three-bonded carbon atoms with only pentagonal and hexagonal rings has exactly pentagons. Many viruses have icosahedral shells whose protein units form hexamers with exactly pentamers (the Caspar–Klug theory, 1962). When a large number of particles crystallises on a sphere, the hexagonal order must contain defects of total "topological charge" . And the hairy ball theorem is a theorem about weather: a continuous horizontal wind field on the globe must have a calm point somewhere. These are honest consequences of , applied to idealised models.
History and global context
- Regular solids. Book XIII of Euclid's Elements (c. 300 BCE) constructs the five regular solids and proves there are no others; the classification is traditionally credited to Theaetetus, and Plato's Timaeus associated them with the elements, hence "Platonic". In 10th-century Baghdad, Abū al-Wafāʾ al-Būzjānī's book of geometric constructions for craftsmen included constructions of polyhedra inscribed in a sphere. Johannes Kepler (1619) studied the regular and semi-regular solids and the star polyhedra.
- Descartes and Euler. René Descartes's manuscript De solidorum elementis (c. 1630) contains the angle-defect theorem; it was lost, survived in a copy made by Gottfried Wilhelm Leibniz in 1676, and was published only in 1860. Leonhard Euler stated in a letter to Christian Goldbach (1750) and published it in 1758; his attempted proof had a gap.
- Proofs and exceptions. Adrien-Marie Legendre gave the first correct proof (1794), using spherical geometry and the area formula for spherical triangles. Augustin-Louis Cauchy (1813) gave the proof by flattening and reducing the graph. Simon Lhuilier (1813) found the polyhedra with tunnels, for which . Imre Lakatos's Proofs and Refutations (1976) is a celebrated dialogue built on this history.
- Surfaces. August Möbius and Johann Benedict Listing independently discovered the Möbius band in 1858. Felix Klein described the Klein bottle in 1882. Walther von Dyck (1888) classified closed surfaces, including the relation , and Henri Poincaré's Analysis Situs (1895) introduced the Betti numbers and the alternating sum. The first fully rigorous proof of the classification, for triangulated surfaces, is due to Henry Brahana (1921), building on work of Max Dehn and Poul Heegaard (1907); Tibor Radó (1925) proved that every surface can be triangulated.
- Today. The Euler characteristic has been generalised to all dimensions and many settings — from Poincaré–Hopf and Gauss–Bonnet–Chern to the Euler characteristic of categories — and Euler's formula remains a starting point for graph theory, chemistry and computer graphics, where meshes are checked with .
Further reading
- David S. Richeson, Euler's Gem: The Polyhedron Formula and the Birth of Topology (2008) — the whole story, from Plato to Poincaré, for a general reader.
- Imre Lakatos, Proofs and Refutations: The Logic of Mathematical Discovery (1976) — a dialogue about what Euler's formula really says.
- Jean Gallier and Dianna Xu, A Guide to the Classification Theorem for Compact Surfaces (2013) — a complete, careful proof.
- M. A. Armstrong, Basic Topology (1983) — surfaces, the Euler characteristic, triangulations and the classification theorem.
- William S. Massey, Algebraic Topology: An Introduction (1967), chapter 1 — the classic account of the classification by cutting and pasting.
- George K. Francis and Jeffrey R. Weeks, "Conway's ZIP proof", American Mathematical Monthly 106 (1999).
- Jeffrey R. Weeks, The Shape of Space (1985; 2nd ed. 2002) — surfaces and three-dimensional manifolds, intuitively.