7. Tiling a Rectangle
Stan Wagon's theorem (Fourteen Proofs of a Result About Tiling a Rectangle, Amer. Math. Monthly
94 (1987) 601–617) states: whenever a rectangle is tiled by finitely many rectangles, each of
which has at least one integer side, then the tiled rectangle has at least one integer side. Here a
tiling is a covering by axis-parallel rectangles with pairwise-disjoint interiors.
Lean code for Definition7.1●1 definition
Associated Lean declarations
-
IntegerRectangleTheorem[complete]
-
IntegerRectangleTheorem[complete]
-
defdefined in DifferentProofs/IntegerRectangle/Defs.leancomplete
def IntegerRectangleTheorem : Prop
def IntegerRectangleTheorem : Prop
**The integer-rectangle tiling theorem** (Wagon). If a rectangle is tiled by finitely many rectangles, each having at least one integer side, then the tiled rectangle has at least one integer side.
The first three proofs below are analytic and share one mechanism. To a rectangle [a,b] \times [c,d] attach the
number \int\!\!\int g(x)\,h(y)\,dx\,dy, which by Fubini factors as
\bigl(\int_a^b g\bigr)\bigl(\int_c^d h\bigr). This functional is additive over a tiling because
the tiles are pairwise almost-disjoint (their overlaps lie in null boundaries), so it is captured by
one lemma.
Let T tile R and let g, h be integrable one-variable functions. If for every tile either its
width-integral of g or its height-integral of h vanishes, then the same dichotomy holds for the
ambient rectangle: either \int g over the width of R vanishes, or \int h over its height does.
Lean code for Lemma7.2●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Basic.leancomplete
theorem IntegerRectangle.IsTiling.prod_integral_dichotomy {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {L : Type} [RCLike L] {g h : ℝ → L} (hT : IntegerRectangle.IsTiling R T) (hint : MeasureTheory.IntegrableOn (fun z ↦ g z.1 * h z.2) R.toSet MeasureTheory.volume) (htile : ∀ (i : ι), ∫ (x : ℝ) in Set.Icc (T i).x₀ (T i).x₁, g x = 0 ∨ ∫ (y : ℝ) in Set.Icc (T i).y₀ (T i).y₁, h y = 0) : ∫ (x : ℝ) in Set.Icc R.x₀ R.x₁, g x = 0 ∨ ∫ (y : ℝ) in Set.Icc R.y₀ R.y₁, h y = 0
theorem IntegerRectangle.IsTiling.prod_integral_dichotomy {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {L : Type} [RCLike L] {g h : ℝ → L} (hT : IntegerRectangle.IsTiling R T) (hint : MeasureTheory.IntegrableOn (fun z ↦ g z.1 * h z.2) R.toSet MeasureTheory.volume) (htile : ∀ (i : ι), ∫ (x : ℝ) in Set.Icc (T i).x₀ (T i).x₁, g x = 0 ∨ ∫ (y : ℝ) in Set.Icc (T i).y₀ (T i).y₁, h y = 0) : ∫ (x : ℝ) in Set.Icc R.x₀ R.x₁, g x = 0 ∨ ∫ (y : ℝ) in Set.Icc R.y₀ R.y₁, h y = 0
**The dichotomy engine.** Suppose `T` tiles `R`, the product `g z.1 · h z.2` is integrable over `R`, and for every tile at least one of its width-integral of `g` or its height-integral of `h` vanishes. Then the same dichotomy holds for the ambient rectangle `R`.
By Fubini the plane integral of g(x)h(y) over any rectangle factors as the product of the two
coordinate integrals. Additivity of the plane integral over the tiling — valid since distinct tiles
meet only in their measure-zero boundaries — writes \int\!\!\int_R g\,h as the sum over tiles of
\int\!\!\int_{T_i} g\,h. Each summand is a product with a vanishing factor, so it is 0; hence
\bigl(\int_R g\bigr)\bigl(\int_R h\bigr) = 0, and a product of reals (or complex numbers) vanishes
only if a factor does.
First proof: a complex double integral, de Bruijn's original method.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.3●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_ComplexIntegral[complete]
-
IntegerRectangleTheorem_ComplexIntegral[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/ComplexIntegral.leancomplete
theorem IntegerRectangleTheorem_ComplexIntegral : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_ComplexIntegral : IntegerRectangleTheorem
**Complex double-integral proof** (de Bruijn) of the integer-rectangle tiling theorem.
Take g(x) = h(x) = e^{2\pi i x}. The one-dimensional integral
\int_a^b e^{2\pi i x}\,dx = (e^{2\pi i b} - e^{2\pi i a})/(2\pi i) vanishes if and only if e^{2\pi i(b-a)} = 1,
i.e. b - a \in \mathbb{Z}. So a tile's coordinate integral vanishes exactly when that side is an
integer; the hypothesis gives the per-tile dichotomy, the engine Lemma 7.2
transports it to R, and the same criterion reads off an integer side. The complex exponential is
what makes the criterion an exact "integer side" statement, with no reflected solutions.
Second proof: a real double integral (Wagon's specialization of the first).
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.4●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_RealIntegral[complete]
-
IntegerRectangleTheorem_RealIntegral[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/RealIntegral.leancomplete
theorem IntegerRectangleTheorem_RealIntegral : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_RealIntegral : IntegerRectangleTheorem
**Real double-integral proof** of the integer-rectangle tiling theorem.
Use the real integrand \sin(2\pi(x - R_x))\sin(2\pi(y - R_y)), where (R_x, R_y) is the corner of
R; shifting the integrand by the corner replaces Wagon's "place R in standard position". The
factor integral is \int_a^b \sin(2\pi(x-s))\,dx = (\cos 2\pi(a-s) - \cos 2\pi(b-s))/(2\pi). It
vanishes whenever b - a \in \mathbb{Z} (used for the tiles, where the shift is irrelevant); and at
the corner, where the lower limit equals the shift, it reduces to (1 - \cos 2\pi(b-s))/(2\pi),
which vanishes if and only if b - s \in \mathbb{Z}. The engine Lemma 7.2 then
forces an integer side of R.
Third proof: a checkerboard colouring (Rochberg–Stein), the discretization of the second.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.5●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_Checkerboard[complete]
-
IntegerRectangleTheorem_Checkerboard[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Checkerboard.leancomplete
theorem IntegerRectangleTheorem_Checkerboard : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_Checkerboard : IntegerRectangleTheorem
**Checkerboard proof** (Rochberg–Stein) of the integer-rectangle tiling theorem.
Colour the plane in a \tfrac12 \times \tfrac12 checkerboard with a corner at R's corner;
"equal black and white" over a region means \int\!\!\int (-1)^{\lfloor 2x\rfloor}(-1)^{\lfloor 2y\rfloor} = 0.
The one-dimensional factor (-1)^{\lfloor 2(x-s)\rfloor} is the \pm 1 square wave of period 1;
its integral over any integer-length interval is 0, so every tile with an integer side is balanced.
By the engine Lemma 7.2 so is R. But over [s, b] the square wave integrates
to the triangle wave \min(r, 1-r), with r the fractional part of b - s, which is nonzero
unless b - s \in \mathbb{Z}; hence R has an integer side.
Fourth proof: counting squares (Ruzsa, Gilbert). Wagon translates every grid line of the tiling
that lies off the lattice through the corner of R onto the nearest half-integer line, leaving
lattice lines fixed; the tiling becomes a tiling of a translated rectangle all of whose
coordinates sit on the half-unit grid, so every rectangle in it is a union of
\tfrac12 \times \tfrac12 squares — the checkerboard cells of the third proof — and the argument
is a parity count of those squares. As with the polynomial proof below, the fg-area supplies the
count without the auxiliary tiling having to be built.
Measure a coordinate x from a base point a by the integer
c(x) = \lfloor x - a \rfloor + \lceil x - a \rceil, twice the translated coordinate of x on
the half-unit grid based at a. Then c(x) is even exactly when x - a is an integer.
Lean code for Lemma7.6●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CountingSquares.leancomplete
theorem IntegerRectangle.CountingSquares.even_cellIndex_iff {a x : ℝ} : Even (IntegerRectangle.CountingSquares.cellIndex a x) ↔ ∃ n, x - a = ↑n
theorem IntegerRectangle.CountingSquares.even_cellIndex_iff {a x : ℝ} : Even (IntegerRectangle.CountingSquares.cellIndex a x) ↔ ∃ n, x - a = ↑n
**The parity criterion.** A grid coordinate is even exactly when the point sits an integer distance from the base point — the translation moves it to a half-integer line otherwise.
Floor and ceiling agree at the integers and differ by one everywhere else, so c(x) is
2\lfloor x - a\rfloor in the first case and 2\lfloor x - a\rfloor + 1 in the second.
The number of half-unit squares covered by the translation of a rectangle — the product of the increments of the two grid coordinates across it — is additive over a tiling.
Lean code for Lemma7.7●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CountingSquares.leancomplete
theorem IntegerRectangle.CountingSquares.sum_cellCount {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (a b : ℝ) : ∑ i, IntegerRectangle.CountingSquares.cellCount a b (T i) = IntegerRectangle.CountingSquares.cellCount a b R
theorem IntegerRectangle.CountingSquares.sum_cellCount {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (a b : ℝ) : ∑ i, IntegerRectangle.CountingSquares.cellCount a b (T i) = IntegerRectangle.CountingSquares.cellCount a b R
**The square count is additive over a tiling.** This is what Wagon obtains by translating the grid lines of the tiling into an auxiliary tiling of the translated rectangle; here it is the fg-area additivity of the thirteenth proof, applied to the grid coordinates.
That number is by definition the fg-area of the pair of grid coordinate functions, so this is fg-area additivity Lemma 7.33, read back in the integers. It is what Wagon gets from the auxiliary tiling, here without having to check that the translated tiles tile the translated rectangle.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.8●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_CountingSquares[complete]
-
IntegerRectangleTheorem_CountingSquares[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/CountingSquares.leancomplete
theorem IntegerRectangleTheorem_CountingSquares : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_CountingSquares : IntegerRectangleTheorem
**Counting-squares proof** (Ruzsa, Gilbert) of the integer-rectangle tiling theorem. Base the half-unit grid at the lower-left corner of `R`. Every tile has an integer side, hence covers an even number of squares, and therefore so does `R`. The corner of `R` has grid coordinate `0`, so the square count of `R` is the product of the grid coordinates of its two far edges; one of them is even, which says that the corresponding side of `R` has integer length.
Base the half-unit grid at the lower-left corner of R. The endpoints of a side of integer
length n are n apart, so the translation moves them equally and the increment of the grid
coordinate across that side is 2n: every tile covers an even number of squares, and hence
Lemma 7.7 so does R. The corner of R has grid coordinate 0, so
that count is the product of the grid coordinates of the far edges of R, and one of the two
factors is even — which says Lemma 7.6 that the corresponding side of
R has integer length. (Wagon phrases the last step as a contradiction: a translated rectangle
with no integer side has both sides equal to half an odd integer, hence an odd number of squares.)
Fifth proof: polynomials (Douady). Through the lower-left corner of R, fix the two coordinate
lattices and introduce a parameter t. Move a vertical grid line by t when its x-coordinate is
off the x-lattice, and move a horizontal grid line by t when its y-coordinate is off the
y-lattice; leave lattice lines fixed. The perturbed areas become honest polynomials in t; the
fg-area formalizes them without separately constructing the auxiliary tiling.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.9●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_Polynomials[complete]
-
IntegerRectangleTheorem_Polynomials[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Polynomials.leancomplete
theorem IntegerRectangleTheorem_Polynomials : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_Polynomials : IntegerRectangleTheorem
**Polynomial proof** (Douady) of the integer-rectangle tiling theorem. The perturbed area of each tile is a polynomial that is linear or constant in the perturbation parameter, while a tiled rectangle with no integer side would have a genuinely quadratic one; comparing `X ^ 2` coefficients in the polynomial identity supplied by fg-area additivity gives `0 = 1`.
Let \varepsilon_x(u) be 0 when u - R_x \in \mathbb{Z} and 1 otherwise, and similarly
define \varepsilon_y; perturb the coordinates by \varphi_t(u) = u + t\varepsilon_x(u) and
\psi_t(v) = v + t\varepsilon_y(v). The perturbed area of a rectangle S is then the value at
t of the polynomial P_S = (\Delta\varepsilon_x X + w)(\Delta\varepsilon_y X + h), with
w, h the sides of S and \Delta\varepsilon the indicator increments across them; its
quadratic coefficient is the fg-area of the indicator pair. If a tile has an integer side, the two
endpoints of that side have the same indicator, the corresponding factor is constant, and the
quadratic coefficient vanishes: the tile's perturbed area is linear or constant in t, as in
Wagon's text. Additivity of the fg-area Lemma 7.33 equates \sum_i P_{T_i}
with P_R at every real t — Wagon needs t small so that the moved segments still bound a
tiling, the algebraic identity does not — hence \sum_i P_{T_i} = P_R as polynomials. If neither
side of R is an integer, each lower endpoint has indicator 0 and each upper endpoint 1,
so the quadratic coefficient of P_R is 1; comparing X^2-coefficients yields 0 = 1, a
contradiction. (A polynomial-free variant of the same computation: each tile's term is affine in
t, so the second finite difference F(2) - 2F(1) + F(0) of the identity vanishes tile by
tile, while it equals 2 on (w + t)(h + t).)
Sixth proof: prime numbers (Robinson). Wagon scales the tiling by a prime p and rounds all tile
corners to integers, which requires verifying that the rounded rectangles tile again. Instead we
count lattice points: rounding is hidden inside a floor, and the re-tiling is replaced by the fact
that the half-open cells of a tiling — each tile minus its left and bottom edges — genuinely
partition the half-open cell of R, with no null sets involved.
The half-open cells of the tiles of a tiling are pairwise disjoint and their union is the half-open cell of the tiled rectangle.
Lean code for Lemma7.10●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Basic.leancomplete
theorem IntegerRectangle.IsTiling.iUnion_toSetIoc {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : ⋃ i, (T i).toSetIoc = R.toSetIoc
theorem IntegerRectangle.IsTiling.iUnion_toSetIoc {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : ⋃ i, (T i).toSetIoc = R.toSetIoc
**Half-open cells of a tiling cover the half-open cell of the tiled rectangle.** For the inclusion that matters, a point of the ambient cell is approached from below-left; finitely many tiles force one of them to contain the approaching points arbitrarily close in, and that tile's half-open cell contains the point.
Disjointness: a point common to two half-open cells moves down-and-left — to the midpoint between
the higher of the two lower-left corners and the point itself — into the interiors of both tiles,
contradicting interior-disjointness. Covering: a point of the ambient half-open cell is approached
from below-left; every such nudge stays in R, hence in some tile, and since there are finitely
many tiles one tile contains nudges arbitrarily close in. That tile is closed, so it contains the
point, and the nudges witness the two strict inequalities of its half-open cell.
For p > 0, the number of points of the lattice \tfrac1p\mathbb{Z} \times \tfrac1p\mathbb{Z}
in the half-open cell of R is the sum of the numbers of such points in the half-open cells of
the tiles. Moreover the count for a rectangle [x_0,x_1] \times [y_0,y_1] is the product
(\lfloor p x_1 \rfloor - \lfloor p x_0 \rfloor)(\lfloor p y_1 \rfloor - \lfloor p y_0 \rfloor).
Lean code for Lemma7.11●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Primes.leancomplete
theorem IntegerRectangle.Primes.card_latticePoints_eq_sum {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {p : ℕ} (hp : 0 < p) : (IntegerRectangle.Primes.latticePoints p R).card = ∑ i, (IntegerRectangle.Primes.latticePoints p (T i)).card
theorem IntegerRectangle.Primes.card_latticePoints_eq_sum {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {p : ℕ} (hp : 0 < p) : (IntegerRectangle.Primes.latticePoints p R).card = ∑ i, (IntegerRectangle.Primes.latticePoints p (T i)).card
**Additivity of the lattice count over a tiling.** The half-open cells of the tiles partition the half-open cell of `R` (`IsTiling.iUnion_toSetIoc`, `IsTiling.pairwiseDisjoint_toSetIoc`), and counting lattice points respects exact partitions. This is where Wagon's "scale by `p` and round all corners" is replaced by counting, with no auxiliary re-tiling.
A lattice point (a/p, b/p) lies in the half-open cell iff \lfloor p x_0\rfloor < a \le
\lfloor p x_1\rfloor and likewise for b, which gives the product formula; additivity is then
exactly the exact-partition property Lemma 7.10 of the half-open cells, read
through this membership description.
If every tile has an integer side, then for every prime p the width or the height of R is
within 1/p of an integer.
Lean code for Lemma7.12●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Primes.leancomplete
theorem IntegerRectangle.Primes.exists_side_near_int {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) {p : ℕ} (hp : Nat.Prime p) : (∃ n, |R.width - ↑n| < 1 / ↑p) ∨ ∃ n, |R.height - ↑n| < 1 / ↑p
theorem IntegerRectangle.Primes.exists_side_near_int {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) {p : ℕ} (hp : Nat.Prime p) : (∃ n, |R.width - ↑n| < 1 / ↑p) ∨ ∃ n, |R.height - ↑n| < 1 / ↑p
**Wagon's claim.** For every prime `p`, some side of the tiled rectangle is within `1/p` of an integer.
A tile side of integer length n contributes the floor-difference factor
\lfloor p x_0 + pn\rfloor - \lfloor p x_0\rfloor = pn, so every tile's lattice count is
divisible by p, and by additivity Lemma 7.11 so is the count of R, a
product of two floor differences. Primality forces p to divide one factor, say
\lfloor p x_1\rfloor - \lfloor p x_0\rfloor = pm; then p(x_1 - x_0) - pm is a difference of
two floor remainders, each in [0,1), so |width - m| < 1/p.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.13●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_Primes[complete]
-
IntegerRectangleTheorem_Primes[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Primes.leancomplete
theorem IntegerRectangleTheorem_Primes : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_Primes : IntegerRectangleTheorem
**Prime-numbers proof** (Robinson) of the integer-rectangle tiling theorem.
Suppose neither side of R is an integer. Each of the width and the height then keeps some fixed
positive distance from every integer — at least the smaller of its fractional part and one minus
it. Choosing a prime p larger than the reciprocals of both distances (there are infinitely many
primes), no side of R can be within 1/p of an integer, contradicting the claim
Lemma 7.12 for this p.
Seventh proof: an Eulerian path (Paterson). Let \Gamma be the graph whose vertices are the
corners of the tiles, two of them joined whenever they are the two ends of a horizontal side of a
tile of integer width, or of a vertical side of a tile of integer height. A tile having a vertex as
a corner contributes exactly one edge there, so the degree of a vertex is the number of tiles
having it as a corner: 2 or 4 away from the corners of R, while a corner of R lies on
exactly one tile and has degree 1. A walk that starts at a corner of R and repeats no edge
can therefore not stop before it reaches another corner of R. Every edge of \Gamma is a
segment of integer length parallel to an axis, so the two corners differ by a vector with integer
entries, and that is an integer side of R.
Of the degrees only the parity is ever used. Wagon reads it off the local picture — a point other
than a corner of R is a corner of 2 or 4 tiles — which is a statement about how tiles fit
together around a point. It follows instead from the fg-area additivity of the thirteenth proof
below, with no local analysis at all, in the form of the corner parity lemma; that lemma and the
double count following it are shared with the eighth proof. Corners are counted with multiplicity,
so degenerate tiles need no separate treatment.
Let T tile R. At every point of the plane, the tiles have in total a number of corners
congruent modulo 2 to the number of corners of R there. (Each rectangle has four corners,
counted with multiplicity.)
Lean code for Lemma7.14●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CornerCount.leancomplete
theorem IntegerRectangle.IsTiling.sum_cornerCount_mod_two {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (u v : ℝ) : ↑(∑ i, IntegerRectangle.cornerCount (T i) u v) = ↑(IntegerRectangle.cornerCount R u v)
theorem IntegerRectangle.IsTiling.sum_cornerCount_mod_two {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (u v : ℝ) : ↑(∑ i, IntegerRectangle.cornerCount (T i) u v) = ↑(IntegerRectangle.cornerCount R u v)
**Corner parity of a tiling.** At every point of the plane, the tiles of a tiling have in total a number of corners congruent mod `2` to the number of corners of the tiled rectangle there. Away from the corners of `R` it says that a point is a corner of evenly many tiles, which is Wagon's "`2` or `4` tiles"; at a corner of `R` the count is odd. The signed corner count is the fg-area for the pair of indicator functions of the coordinate lines through the point, hence additive over the tiling; forgetting the signs is passing to `ZMod 2`.
Fix a point (u, v) and take for f and g the indicator functions of \{u\} and
\{v\}. The fg-area of a rectangle is then
(\mathbb{1}[x_1 = u] - \mathbb{1}[x_0 = u])(\mathbb{1}[y_1 = v] - \mathbb{1}[y_0 = v]), the
number of corners at (u, v) with the left and bottom edges counted negatively. Being an fg-area
it is additive over the tiling Lemma 7.33, and modulo 2 subtraction and
addition agree, so each signed count may be replaced by the corner count.
Let T tile R and let Z be a finite set of points of the plane in which every tile has an
even number of corners. Then R has an even number of corners in Z.
Lean code for Lemma7.15●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CornerCount.leancomplete
theorem IntegerRectangle.IsTiling.even_sum_cornerCount {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {Z : Finset (ℝ × ℝ)} (h : ∀ (i : ι), Even (∑ z ∈ Z, IntegerRectangle.cornerCount (T i) z.1 z.2)) : Even (∑ z ∈ Z, IntegerRectangle.cornerCount R z.1 z.2)
theorem IntegerRectangle.IsTiling.even_sum_cornerCount {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {Z : Finset (ℝ × ℝ)} (h : ∀ (i : ι), Even (∑ z ∈ Z, IntegerRectangle.cornerCount (T i) z.1 z.2)) : Even (∑ z ∈ Z, IntegerRectangle.cornerCount R z.1 z.2)
**The double count.** Let `T` tile `R` and let `Z` be a finite set of points such that every tile has an even number of corners in `Z`. Then so has `R`. Count the incidences between the points of `Z` and the tiles having them as a corner: tile by tile the total is even by hypothesis, and point by point the corner parity (`IsTiling.sum_cornerCount_mod_two`) replaces each count by the corresponding count for `R`.
Count the incidences between the points of Z and the tiles having them as a corner. Tile by
tile the total is even by hypothesis. Counting the same incidences point by point instead, and
replacing each point's count by the corresponding count for R
Lemma 7.14, leaves the parity unchanged, so the number of corners of
R in Z is even too.
Let T tile R, every tile having an integer side. Then some walk in \Gamma leads from the
lower-left corner of R to another corner of R.
Lean code for Lemma7.16●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/EulerianPath.leancomplete
theorem IntegerRectangle.EulerianPath.exists_reachable_corner {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : IntegerRectangle.EulerianPath.Reachable T (R.x₀, R.y₀) (R.x₁, R.y₀) ∨ IntegerRectangle.EulerianPath.Reachable T (R.x₀, R.y₀) (R.x₀, R.y₁) ∨ IntegerRectangle.EulerianPath.Reachable T (R.x₀, R.y₀) (R.x₁, R.y₁)
theorem IntegerRectangle.EulerianPath.exists_reachable_corner {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : IntegerRectangle.EulerianPath.Reachable T (R.x₀, R.y₀) (R.x₁, R.y₀) ∨ IntegerRectangle.EulerianPath.Reachable T (R.x₀, R.y₀) (R.x₀, R.y₁) ∨ IntegerRectangle.EulerianPath.Reachable T (R.x₀, R.y₀) (R.x₁, R.y₁)
**The walk of Paterson's proof.** A walk in `Γ` leads from the lower-left corner of `R` to another of its corners. The lower-left corner lies in its own component, so `R` has an odd number of corners there unless a second one does too; but the tiles have an even number of corners in the component, and by corner parity so has `R`.
Take for Z the connected component of the lower-left corner of R, that is, the vertices a
walk starting there reaches. An edge of \Gamma has both of its ends in Z or neither, and the
sides that a tile with an integer side contributes to \Gamma pair up its four corners; so every
tile has an even number of corners in Z, and by the double count
Lemma 7.15 so has R. The lower-left corner of R is one of them,
hence not the only one.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.17●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_EulerianPath[complete]
-
IntegerRectangleTheorem_EulerianPath[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/EulerianPath.leancomplete
theorem IntegerRectangleTheorem_EulerianPath : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_EulerianPath : IntegerRectangleTheorem
**Eulerian-path proof** (Paterson) of the integer-rectangle tiling theorem. A walk in `Γ` joins the lower-left corner of `R` to another of its corners, and moves by a vector with integer entries; whichever corner it reaches, that is an integer side of `R`.
An edge of \Gamma is a side of a tile, parallel to an axis and of integer length, so it leaves
the pair of fractional parts of a point unchanged, and hence so does a walk. The walk to a second
corner of R Lemma 7.16 therefore preserves the fractional part of the
abscissa or of the ordinate — of both, if it ends at the opposite corner — which says that the
width or the height of R is an integer.
Eighth proof: a bipartite graph, Wagon's variation on the preceding proof. Place R in standard
position and join each point of the lattice \mathbb{Z} \times \mathbb{Z} to the tiles having it
as a corner; then count the edges of that graph in the two possible ways. It is the same count as
before, taken over a lattice grid instead of a connected component of \Gamma. The lattice used
below is the one through the lower-left corner of R, which replaces the standard position, and
rather than the tile corners the count runs over all lattice points of R, which changes nothing
since a non-corner contributes 0 on both sides.
Let T tile R, and let X and Y be finite sets of abscissae and of ordinates such that
every tile has both or neither of its vertical edges over X, or both or neither of its
horizontal edges over Y. Then R has an even number of corners on the grid X \times Y.
Lean code for Lemma7.18●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/BipartiteGraph.leancomplete
theorem IntegerRectangle.BipartiteGraph.even_sum_cornerCount {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {X Y : Finset ℝ} (h : ∀ (i : ι), ((T i).x₀ ∈ X ↔ (T i).x₁ ∈ X) ∨ ((T i).y₀ ∈ Y ↔ (T i).y₁ ∈ Y)) : Even (∑ z ∈ X ×ˢ Y, IntegerRectangle.cornerCount R z.1 z.2)
theorem IntegerRectangle.BipartiteGraph.even_sum_cornerCount {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {X Y : Finset ℝ} (h : ∀ (i : ι), ((T i).x₀ ∈ X ↔ (T i).x₁ ∈ X) ∨ ((T i).y₀ ∈ Y ↔ (T i).y₁ ∈ Y)) : Even (∑ z ∈ X ×ˢ Y, IntegerRectangle.cornerCount R z.1 z.2)
**Counting the edges of the bipartite graph.** Let `X` and `Y` be finite sets of abscissae and ordinates, and suppose each tile has either both or neither of its vertical edges over `X`, or both or neither of its horizontal edges over `Y`. Then the tiled rectangle has an even number of corners on the grid `X × Y`. Each tile contributes an even number of edges to the graph joining the grid points to the tiles having them as a corner, so the double count (`IsTiling.even_sum_cornerCount`) applies.
The number of corners a rectangle has on the grid is the number of its vertical edges over X
times the number of its horizontal edges over Y, so by hypothesis every tile has an even number
of them, and the double count Lemma 7.15 applies.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.19●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_BipartiteGraph[complete]
-
IntegerRectangleTheorem_BipartiteGraph[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/BipartiteGraph.leancomplete
theorem IntegerRectangleTheorem_BipartiteGraph : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_BipartiteGraph : IntegerRectangleTheorem
**Bipartite-graph proof** (Wagon's variation on Paterson's Eulerian-path proof) of the integer-rectangle tiling theorem. Take for `X` and `Y` the lattices through the lower-left corner of `R`, so that a tile with an integer side has both or neither of its edges in that direction on the lattice, and the double count (`even_sum_cornerCount`) applies: `R` has an even number of corners on the lattice. Its lower-left corner is one of them, so if neither side of `R` were an integer it would be the only one.
Take for X and Y the points of the lattices through the left and bottom edges of R that
lie inside R. A tile of integer width has its two vertical edges an integer apart, so both or
neither lie on the lattice, and likewise in the other direction; the hypothesis of the count
Lemma 7.18 therefore holds, and R has evenly many corners on the
grid. Its lower-left corner is one of them. If neither side of R were an integer, its right
edge would miss X and its top edge would miss Y, leaving that corner as the only one — an
odd number.
Ninth proof: induction (Raphael Robinson). Call a tile an H-tile if it is designated by its
integer width and a V-tile if it is designated by its integer height. Cutting every tile into
unit pieces along its designated side normalizes the tiling: every H-tile is then exactly one unit
wide and every V-tile exactly one unit tall. The induction runs on the number of H-tiles. Robinson
grows a vertical strip of width 1 from an H-tile, expanding it one unit at a time through the
V-tiles above it until an H-tile blocks the way, then stepping onto that H-tile and carrying on;
and likewise downwards. The resulting staircase runs from the bottom edge of R to its top edge,
and deleting it and sliding everything on its right one unit leftwards tiles a rectangle one unit
narrower with fewer H-tiles.
Every tiling by tiles with an integer side refines to a normalized one, in which every tile is one unit wide or one unit tall.
Lean code for Lemma7.20●1 theorem
Associated Lean declarations
-
IntegerRectangle.IsTiling.normalized[complete]
-
IntegerRectangle.IsTiling.normalized[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Staircase.leancomplete
theorem IntegerRectangle.IsTiling.normalized {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hx : R.x₀ < R.x₁) (hy : R.y₀ < R.y₁) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : IntegerRectangle.Staircase.Normalized R (IntegerRectangle.Staircase.pieceTiles T) (IntegerRectangle.Staircase.PieceCutsWidth T)
theorem IntegerRectangle.IsTiling.normalized {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hx : R.x₀ < R.x₁) (hy : R.y₀ < R.y₁) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : IntegerRectangle.Staircase.Normalized R (IntegerRectangle.Staircase.pieceTiles T) (IntegerRectangle.Staircase.PieceCutsWidth T)
**Cutting each tile into unit pieces normalizes a tiling.** Every tile has a side of integer length, at least one unit long since the tile is nondegenerate, and the half-open cells of the pieces of a tile partition its own.
Discard the degenerate tiles and cut each remaining tile into unit pieces along a side of integer
length, of which it has at least one, and which is at least one unit long since the tile is
nondegenerate. The half-open cells of the pieces of a tile partition its own, so the cells of all
the pieces still partition those of R.
-
IntegerRectangle.Staircase.exists_column[complete]
In a normalized tiling the strip of width 1 carried by an H-tile runs upwards through whole
V-tiles until it reaches the top of R or an H-tile starts across it.
Lean code for Lemma7.21●1 theorem
Associated Lean declarations
-
IntegerRectangle.Staircase.exists_column[complete]
-
IntegerRectangle.Staircase.exists_column[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Staircase.leancomplete
theorem IntegerRectangle.Staircase.exists_column {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {H : ι → Prop} (hn : IntegerRectangle.Staircase.Normalized R T H) {k : ι} (hk : H k) : ∃ hi, (T k).y₁ ≤ hi ∧ hi ≤ R.y₁ ∧ (∀ (j : ι) (y : ℝ), (T j).y₀ < y → y ≤ (T j).y₁ → (T k).y₀ < y → y ≤ hi → (T j).x₁ ≤ (T k).x₀ ∨ (T k).x₀ + 1 ≤ (T j).x₀ ∨ (T k).y₀ ≤ (T j).y₀ ∧ (T j).y₁ ≤ hi ∧ (H j → (T j).x₀ = (T k).x₀ ∧ (T j).x₁ = (T k).x₀ + 1)) ∧ (hi = R.y₁ ∨ ∃ k', H k' ∧ (T k').y₀ = hi ∧ (T k').x₀ < (T k).x₀ + 1 ∧ (T k).x₀ < (T k').x₁)
theorem IntegerRectangle.Staircase.exists_column {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {H : ι → Prop} (hn : IntegerRectangle.Staircase.Normalized R T H) {k : ι} (hk : H k) : ∃ hi, (T k).y₁ ≤ hi ∧ hi ≤ R.y₁ ∧ (∀ (j : ι) (y : ℝ), (T j).y₀ < y → y ≤ (T j).y₁ → (T k).y₀ < y → y ≤ hi → (T j).x₁ ≤ (T k).x₀ ∨ (T k).x₀ + 1 ≤ (T j).x₀ ∨ (T k).y₀ ≤ (T j).y₀ ∧ (T j).y₁ ≤ hi ∧ (H j → (T j).x₀ = (T k).x₀ ∧ (T j).x₁ = (T k).x₀ + 1)) ∧ (hi = R.y₁ ∨ ∃ k', H k' ∧ (T k').y₀ = hi ∧ (T k').x₀ < (T k).x₀ + 1 ∧ (T k).x₀ < (T k').x₁)
**The column of the staircase above an H-tile.** The strip runs from the bottom of the H-tile up to the height `hi` where it stops. Every tile meeting the strip along the way lies inside the column, and is a V-tile unless it is the H-tile itself; and at `hi` either the strip has reached the top of `R` or an H-tile carries it on.
Induct on the number of unit levels the strip has risen. Nothing crosses the top edge of the
H-tile inside the strip, since the only tile below that edge there is the H-tile itself. If
nothing crosses the height reached so far and no H-tile starts there, then the tile above each
point of that height starts exactly there, hence is a V-tile and is one unit tall; it therefore
spans the whole level, nothing crosses the next height, and the strip is still inside R. Each
level raises the strip by a unit, so it cannot rise forever.
A normalized tiling with an H-tile has a staircase strip of width 1 running from the bottom
edge of R to its top edge and containing an H-tile. Every tile lies to the left of the strip at
each of its heights, or to its right, or inside it, and none lies to the left at one height and to
the right at another.
Lean code for Lemma7.22●1 theorem
Associated Lean declarations
-
IntegerRectangle.Staircase.exists_strip[complete]
-
IntegerRectangle.Staircase.exists_strip[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Staircase.leancomplete
theorem IntegerRectangle.Staircase.exists_strip {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {H : ι → Prop} (hn : IntegerRectangle.Staircase.Normalized R T H) {k : ι} (hk : H k) : ∃ c k₀, IntegerRectangle.Staircase.Strip R T H R.y₀ R.y₁ c ∧ H k₀ ∧ (T k₀).x₀ = c (T k₀).y₁
theorem IntegerRectangle.Staircase.exists_strip {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {H : ι → Prop} (hn : IntegerRectangle.Staircase.Normalized R T H) {k : ι} (hk : H k) : ∃ c k₀, IntegerRectangle.Staircase.Strip R T H R.y₀ R.y₁ c ∧ H k₀ ∧ (T k₀).x₀ = c (T k₀).y₁
**The staircase strip of a normalized tiling.** Grown upwards from an H-tile whose column reaches the bottom of `R`, the staircase runs from the bottom edge of `R` to its top edge, and the H-tile it starts from lies inside it.
Walk down from the given H-tile: while the column below the current H-tile is blocked, step onto
the H-tile blocking it, which lies strictly lower, so the walk stops at an H-tile whose column
reaches the bottom of R. From there build the staircase upwards Lemma 7.21
column by column, each step raising the top edge to a strictly higher one of the finitely many
heights carrying a horizontal edge of the tiling. A tile meeting a column lies inside it, so it
meets no other column, and the strip has a single abscissa along it; and consecutive columns
overlap horizontally, since the H-tile carrying the upper column crosses the lower one. A tile to
the left of the staircase at one height and to its right at another would have to fit in the gap
between two consecutive columns, and there is no gap.
Cutting a normalized tiling along its staircase strip and sliding everything on the right of the strip one unit leftwards tiles the rectangle one unit narrower.
Lean code for Lemma7.23●1 theorem
Associated Lean declarations
-
IntegerRectangle.Staircase.isTiling_cut[complete]
-
IntegerRectangle.Staircase.isTiling_cut[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Staircase.leancomplete
theorem IntegerRectangle.Staircase.isTiling_cut {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {H : ι → Prop} {c : ℝ → ℝ} (hn : IntegerRectangle.Staircase.Normalized R T H) (hs : IntegerRectangle.Staircase.Strip R T H R.y₀ R.y₁ c) (hRx : R.x₀ + 1 < R.x₁) : IntegerRectangle.IsTiling (IntegerRectangle.Staircase.cutRect R ⋯) fun p ↦ IntegerRectangle.Staircase.cutPiece (T p.1) (IntegerRectangle.Staircase.cutAt T c p.1) p.2
theorem IntegerRectangle.Staircase.isTiling_cut {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {H : ι → Prop} {c : ℝ → ℝ} (hn : IntegerRectangle.Staircase.Normalized R T H) (hs : IntegerRectangle.Staircase.Strip R T H R.y₀ R.y₁ c) (hRx : R.x₀ + 1 < R.x₁) : IntegerRectangle.IsTiling (IntegerRectangle.Staircase.cutRect R ⋯) fun p ↦ IntegerRectangle.Staircase.cutPiece (T p.1) (IntegerRectangle.Staircase.cutAt T c p.1) p.2
**Cutting a tiling along a staircase strip tiles the rectangle one unit narrower.** The strip of width `1` that is deleted is exactly the gap that closes when everything to its right slides one unit leftwards, so the half-open cells still partition the shrunken rectangle.
Each tile is cut at a single abscissa: its right edge if it lies left of the strip, its left edge less one if it lies right of the strip, and the left edge of the strip if it lies inside it — and since the staircase is a wall Lemma 7.22 the same alternative holds at all of that tile's heights. A point of the shrunken rectangle left of the strip comes from the point itself and one to its right from its translate one unit rightwards, so the half-open cells of the pieces partition those of the shrunken rectangle.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.24●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_Staircase[complete]
-
IntegerRectangleTheorem_Staircase[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Staircase.leancomplete
theorem IntegerRectangleTheorem_Staircase : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_Staircase : IntegerRectangleTheorem
**Robinson's proof** of the integer-rectangle tiling theorem, by induction on the number of H-tiles. Cutting every tile into unit pieces along its integer side normalizes the tiling, and the induction then runs on normalized tilings.
Normalize the tiling Lemma 7.20 and induct on the number of its H-tiles.
With no H-tile every tile has integer height, hence so does R. Otherwise grow the staircase
from an H-tile Lemma 7.22. If R is narrower than two units then the
H-tile leaves no room beside it and R is exactly one unit wide. Otherwise cut the staircase out
Lemma 7.23: heights never change, so V-tiles stay V-tiles, and an H-tile is
carried over whole or swallowed by the strip, so the new tiling is normalized and has fewer
H-tiles — the one the staircase was grown from is gone. Its rectangle is one unit narrower and
just as tall, so an integer side of it is an integer side of R.
Tenth proof: induction on reducible links (Richard Bishop and Wagon), Wagon's variation on Robinson's induction. Call a tile an H-tile if it is designated by its integer width and a V-tile if it is designated by its integer height. A V-link is a maximal stretch of a vertical line of the tiling that no tile crosses and that no horizontal segment cuts, and an H-link is its horizontal counterpart — so the H-links are the V-links of the transposed tiling. A link is reducible if it is a V-link with only H-tiles along one of its sides, or an H-link with only V-tiles along one of its sides. The proof is an induction on the number of tiles: a reducible link always exists, and reducing it loses a tile.
At every height of a V-link there is a tile whose right edge lies on the link, and it sticks out past neither end of the link.
Lean code for Lemma7.25●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/ReducibleLink.leancomplete
theorem IntegerRectangle.ReducibleLink.Link.exists_left {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hp : IntegerRectangle.Proper T) (l : IntegerRectangle.ReducibleLink.Link R T) {y : ℝ} (hy₀ : l.lo < y) (hy₁ : y ≤ l.hi) : ∃ i, (T i).x₀ < l.c ∧ (T i).x₁ = l.c ∧ l.lo ≤ (T i).y₀ ∧ (T i).y₁ ≤ l.hi ∧ (T i).y₀ < y ∧ y ≤ (T i).y₁
theorem IntegerRectangle.ReducibleLink.Link.exists_left {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hp : IntegerRectangle.Proper T) (l : IntegerRectangle.ReducibleLink.Link R T) {y : ℝ} (hy₀ : l.lo < y) (hy₁ : y ≤ l.hi) : ∃ i, (T i).x₀ < l.c ∧ (T i).x₁ = l.c ∧ l.lo ≤ (T i).y₀ ∧ (T i).y₁ ≤ l.hi ∧ (T i).y₀ < y ∧ y ≤ (T i).y₁
**The tile abutting a V-link on the left at a given height.** At every height of the link there is a tile whose right edge lies on the link, and it sticks out past neither end of the link: those tiles cut the link into consecutive pieces.
Approach the point of the link at that height from below left; the tile whose half-open cell contains it has the line on or to the right of its own right edge. It cannot reach past the line, for a tile crossing the line would block a height interior to the link, and it cannot reach past either end of the link, because whatever blocks that end — a tile crossing the line, or a horizontal edge arriving at the line from both sides — would share a point with it.
Let T tile R, let a V-link of the tiling be given, and let w > 0 be at most the width of
every tile abutting the link on its right. Pushing every tile on the left of the link w units
rightwards, and paring every tile on its right back by w, again tiles R.
Lean code for Lemma7.26●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/ReducibleLink.leancomplete
theorem IntegerRectangle.ReducibleLink.isTiling_push {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hp : IntegerRectangle.Proper T) (hRx : R.x₀ < R.x₁) (hRy : R.y₀ < R.y₁) {l : IntegerRectangle.ReducibleLink.Link R T} {w : ℝ} (hw0 : 0 < w) (hR : ∀ (i : ι), IntegerRectangle.ReducibleLink.IsRight l i → l.c + w ≤ (T i).x₁) : IntegerRectangle.IsTiling R (IntegerRectangle.ReducibleLink.push l w ⋯ hR)
theorem IntegerRectangle.ReducibleLink.isTiling_push {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hp : IntegerRectangle.Proper T) (hRx : R.x₀ < R.x₁) (hRy : R.y₀ < R.y₁) {l : IntegerRectangle.ReducibleLink.Link R T} {w : ℝ} (hw0 : 0 < w) (hR : ∀ (i : ι), IntegerRectangle.ReducibleLink.IsRight l i → l.c + w ≤ (T i).x₁) : IntegerRectangle.IsTiling R (IntegerRectangle.ReducibleLink.push l w ⋯ hR)
**Pushing the tiles on the left of a link rightwards again tiles the same rectangle.** The strip `(c, c + w] × (lo, hi]` that the tiles on the left sweep out is exactly the strip that the tiles on the right vacate, so the cells still partition `R`.
The tiles on either side of the link cut it into consecutive pieces
Lemma 7.25, so the strip of width w that the tiles on the left sweep out
is exactly the strip that the tiles on the right vacate; no other tile can reach into it, and the
half-open cells of the new family therefore still partition those of R.
In a tiling with at least one H-tile and at least one V-tile, some link is reducible.
Lean code for Lemma7.27●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/ReducibleLink.leancomplete
theorem IntegerRectangle.ReducibleLink.exists_reducible {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {H : ι → Prop} (hT : IntegerRectangle.IsTiling R T) (hp : IntegerRectangle.Proper T) {a b : ι} (ha : H a) (hb : ¬H b) : (∃ l, l.Reducible H) ∨ ∃ l, l.Reducible fun i ↦ ¬H i
theorem IntegerRectangle.ReducibleLink.exists_reducible {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {H : ι → Prop} (hT : IntegerRectangle.IsTiling R T) (hp : IntegerRectangle.Proper T) {a b : ι} (ha : H a) (hb : ¬H b) : (∃ l, l.Reducible H) ∨ ∃ l, l.Reducible fun i ↦ ¬H i
**Wagon's crossing argument: some link is reducible.** In a tiling with a tile satisfying `H` and a tile not satisfying it, some V-link is reducible for `H`, or some H-link — a V-link of the transposed tiling — is reducible for the complement of `H`. For suppose not: every V-link has a non-`H`-tile on each side and every H-link an `H`-tile below and above. Walking along links, the `H`-tiles then reach every height of `R`, and the non-`H`-tiles reach from the left edge to the right one; the invariant `RightOfAll` holds at the left edge and survives every step rightwards, which is absurd once the right edge of `R` is reached.
Suppose not. Then from any H-tile one can step to an H-tile directly above or below across an
H-link, so the H-tiles reach every height of R; and from any V-tile one can step to a V-tile
across a V-link on either side, so the V-tiles reach from the left edge of R to its right edge.
Follow the V-tiles rightwards, carrying the assertion that every H-tile overlapping the current
V-tile in height lies to the right of it. It holds at the left edge, where there is no room on the
left. It survives a step: an H-tile lying on the left of the V-link just crossed can be walked up
and down along H-links to the height of the previous V-tile, staying on the left throughout, since
a V-link blocks every H-link it meets and the H-tiles bordering an H-link do not reach past its
ends — contradicting the assertion for the previous V-tile. But at the right edge of R the
assertion is absurd, since the H-tiles reach that height too.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.28●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_ReducibleLink[complete]
-
IntegerRectangleTheorem_ReducibleLink[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/ReducibleLink.leancomplete
theorem IntegerRectangleTheorem_ReducibleLink : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_ReducibleLink : IntegerRectangleTheorem
**Reducible-link proof** (Bishop–Wagon) of the integer-rectangle tiling theorem, by strong induction on the number of tiles. A degenerate `R` has a zero side; a tiling that is not proper loses a degenerate tile; if every tile has integer width, or every tile integer height, the fg-area settles the matter at once; and otherwise some link is reducible (`exists_reducible`) and reducing it (`step_of_reducible`, `step_of_reducible_transpose`) loses a tile.
Induct on the number of tiles. Degenerate tiles have empty half-open cells and may be discarded.
If every tile has integer width the fg-area for the fractional part horizontally and the identity
vertically vanishes on every tile, hence on R, so R has integer width; likewise if every
tile has integer height. Otherwise some link is reducible Lemma 7.27, say
a V-link with only H-tiles on its right; take for w the width of the narrowest of them and push
Lemma 7.26. Heights never change, so V-tiles stay V-tiles, and widths change
by the integer w, so H-tiles stay H-tiles; but the narrowest tile on the right is squeezed to
nothing, so the new tiling of R has fewer tiles and the induction hypothesis applies. The three
other ways a link can be reducible are this one read in the mirror image of the tiling, in its
transpose, and in the mirror image of its transpose.
Twelfth proof: a sweep line (Bachman–Yannakakis). This one does not use the analytic engine above. Instead of an integral it propagates a conserved quantity upward through the tiling, and the only geometry it needs is what a horizontal cut of a tiling looks like — the slice lemma below.
Let T tile R and let t be a height between the bottom and the top of R avoiding every
horizontal tile edge. Then the widths of the tiles crossed by the line y = t add up to the width
of R.
Lean code for Lemma7.29●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/SweepLine.leancomplete
theorem IntegerRectangle.SweepLine.widthSum_slice {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {t : ℝ} (ht₀ : R.y₀ ≤ t) (ht₁ : t ≤ R.y₁) (hgen : t ∉ IntegerRectangle.SweepLine.edgeSet T) : (IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ < t ∧ t < (T i).y₁) = R.width
theorem IntegerRectangle.SweepLine.widthSum_slice {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {t : ℝ} (ht₀ : R.y₀ ≤ t) (ht₁ : t ≤ R.y₁) (hgen : t ∉ IntegerRectangle.SweepLine.edgeSet T) : (IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ < t ∧ t < (T i).y₁) = R.width
**The slice lemma.** Cut a tiling along a horizontal line `y = t` that lies inside the tiled rectangle and misses every tile edge. The line crosses the interiors of the tiles it meets, so their traces on it have pairwise-disjoint interiors and cover the full width of the tiled rectangle; hence the widths of those tiles add up to the width of the tiled rectangle.
Because t avoids the horizontal edges, a tile met by the line at all is crossed through its
interior, and its trace on the line is the closed interval spanned by its width. The traces cover
the full cross-section of R at height t because the tiles cover R, and two distinct traces
meet in a null set: an interior point of both traces would be an interior point of both tiles.
Additivity of one-dimensional Lebesgue measure over this almost-disjoint cover gives the claim.
At every height c strictly between the bottom and the top of R, the tiles whose bottom edge
lies at c (the tiles born at c) have the same total width as the tiles whose top edge lies
at c (the tiles dying at c).
Lean code for Lemma7.30●1 theorem
Associated Lean declarations
-
IntegerRectangle.SweepLine.gain_eq_loss[complete]
-
IntegerRectangle.SweepLine.gain_eq_loss[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/SweepLine.leancomplete
theorem IntegerRectangle.SweepLine.gain_eq_loss {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {c : ℝ} (hc₀ : R.y₀ < c) (hc₁ : c < R.y₁) : (IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ = c ∧ c < (T i).y₁) = IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ < c ∧ c = (T i).y₁
theorem IntegerRectangle.SweepLine.gain_eq_loss {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {c : ℝ} (hc₀ : R.y₀ < c) (hc₁ : c < R.y₁) : (IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ = c ∧ c < (T i).y₁) = IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ < c ∧ c = (T i).y₁
**Flow conservation.** At a height strictly inside the tiled rectangle, the tiles born there have the same total width as the tiles dying there.
The finitely many horizontal tile edges leave a punctured neighbourhood of c edge-free, so the
slice lemma Lemma 7.29 applies at heights just below and just above c, and
both slices total the width of R. The slice below consists of the tiles strictly straddling c
together with those dying at c; the slice above, of the same straddling tiles together with those
born at c. Subtracting the common straddling part equates the gain with the loss.
Call a height integral if it lies an integer distance above the base of R, and suppose every
tile has an integer side. For a height c below the top of R, let the gain G(c) be the
total width of the tiles born at c whose top edge is non-integral, and the loss L(c) the
total width of the tiles dying at c whose top edge is non-integral. Then
G(c) - L(c) \in \mathbb{Z}.
Lean code for Lemma7.31●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/SweepLine.leancomplete
theorem IntegerRectangle.SweepLine.exists_int_jump {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) {c : ℝ} (hc : c < R.y₁) : ∃ n, ((IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ = c ∧ c < (T i).y₁ ∧ ¬IntegerRectangle.SweepLine.IntHeight R (T i).y₁) - IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ < c ∧ c = (T i).y₁ ∧ ¬IntegerRectangle.SweepLine.IntHeight R (T i).y₁) = ↑n
theorem IntegerRectangle.SweepLine.exists_int_jump {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) {c : ℝ} (hc : c < R.y₁) : ∃ n, ((IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ = c ∧ c < (T i).y₁ ∧ ¬IntegerRectangle.SweepLine.IntHeight R (T i).y₁) - IntegerRectangle.SweepLine.widthSum T fun i ↦ (T i).y₀ < c ∧ c = (T i).y₁ ∧ ¬IntegerRectangle.SweepLine.IntHeight R (T i).y₁) = ↑n
**The sweep function only ever jumps by an integer.** Crossing the height `c` gains the tiles born there and loses the tiles dying there. If `c` is at integer height the losses are not counted at all, and each gained tile has an edge at integer height and one at non-integer height, hence integer width. Otherwise the losses are counted in full, so flow conservation cancels them against the gains and leaves exactly the tiles born at `c` whose top edge is at integer height — again tiles with integer width.
A tile with exactly one of its two horizontal edges at integral height has non-integer height,
hence integer width by the hypothesis, and any sum of such widths is an integer. If c is
integral then L(c) = 0 outright — a tile dying at c has its top edge at the integral height
c, so it is not counted — while every tile counted by G(c) has integral bottom and
non-integral top, so G(c) is an integer. If c is not integral (in particular c is strictly
above the base), then every tile dying at c has non-integral top, so L(c) is the full dying
width, which by conservation Lemma 7.30 equals the full born width; hence
G(c) - L(c) is minus the width born at c with integral top, and each such tile has
non-integral bottom and integral top — integer width again.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.32●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_SweepLine[complete]
-
IntegerRectangleTheorem_SweepLine[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/SweepLine.leancomplete
theorem IntegerRectangleTheorem_SweepLine : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_SweepLine : IntegerRectangleTheorem
**Sweep-line proof** (Bachman–Yannakakis) of the integer-rectangle tiling theorem.
Suppose the height of R is not an integer, and sweep a horizontal line up through the tiling. At
height t let f(t) be the total width of the tiles the line meets — each tile taken with its
bottom edge removed — whose top edge is at non-integral height above the base of R. Below R
no tile has been entered, so f = 0. At the top of R exactly the tiles touching the top edge
are counted — their top edge is at the height of R, which is non-integral — and by the slice
lemma Lemma 7.29 applied just below the top these tiles span the full width, so
f ends at the width of R. Between horizontal tile edges f is constant, and crossing a
height c changes it by the gain minus the loss at c, which is an integer
Lemma 7.31. Rather than sorting the finitely many tile edges, this is packaged as
local constancy of t \mapsto \{f(t)\} and settled by connectedness of \mathbb{R}: the
fractional part of the width of R equals the fractional part of f below R, namely 0.
(The jump lemma stops below the top of R — conservation genuinely fails there, that failure
being the theorem — so f is frozen at the top before taking fractional parts.)
Thirteenth proof: step functions (Hochster–Maté). Like the first three this attaches a number to each rectangle and rides on additivity over the tiling, but the number comes from a step function instead of an integral, and the additivity is combinatorial rather than measure-theoretic: it holds for the fg-area built from an arbitrary function, with no regularity at all.
For functions f, g : \mathbb{R} \to \mathbb{R} define the fg-area of a rectangle
[x_0, x_1] \times [y_0, y_1] as (f(x_1) - f(x_0)) \cdot (g(y_1) - g(y_0)). If T tiles R
then the fg-areas of the tiles sum to the fg-area of R, for arbitrary f and g.
Lean code for Lemma7.33●1 theorem
Associated Lean declarations
-
IntegerRectangle.IsTiling.sum_fgArea[complete]
-
IntegerRectangle.IsTiling.sum_fgArea[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/GridRefinement.leancomplete
theorem IntegerRectangle.IsTiling.sum_fgArea {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (f g : ℝ → ℝ) : ∑ i, IntegerRectangle.fgArea f g (T i) = IntegerRectangle.fgArea f g R
theorem IntegerRectangle.IsTiling.sum_fgArea {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (f g : ℝ → ℝ) : ∑ i, IntegerRectangle.fgArea f g (T i) = IntegerRectangle.fgArea f g R
**The fg-area is additive over a tiling** (Wagon, after Hochster and Maté), for arbitrary `f, g : ℝ → ℝ`: summing `(f x₁ - f x₀) · (g y₁ - g y₀)` over the tiles of a tiling gives the same quantity for the tiled rectangle. The tile edges span a grid; every open grid cell lies in exactly one tile, the cells of a tile fill a product of index intervals, and the sum telescopes in both coordinates.
The tile edges form a graph; extending its edges across R cuts R into a grid, whose vertical
lines carry the finitely many x-coordinates of vertical tile edges and whose horizontal lines carry
the y-coordinates of horizontal ones. No grid coordinate lies strictly inside an open grid cell, so
a tile covering the centre of a cell has all four edges clear of it and contains the whole cell; by
disjointness of interiors this tile is unique. Conversely the cells assigned to a tile fill out a
full product subdivision of it, because the tile's own edges are grid lines. Summing fg-areas of
cells therefore counts every cell exactly once, tile by tile; over a product subdivision the sum
telescopes in both coordinates to the tile's fg-area, and over the whole grid it telescopes to the
fg-area of R.
Let f, g : \mathbb{R} \to \mathbb{R} be arbitrary. If T tiles R and every tile has a
vanishing increment of f across its width or of g across its height, then the same dichotomy
holds for R.
Lean code for Lemma7.34●1 theorem
Associated Lean declarations
-
IntegerRectangle.StepFunction.dichotomy[complete]
-
IntegerRectangle.StepFunction.dichotomy[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/StepFunction.leancomplete
theorem IntegerRectangle.StepFunction.dichotomy {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (f g : ℝ → ℝ) (htile : ∀ (i : ι), f (T i).x₁ - f (T i).x₀ = 0 ∨ g (T i).y₁ - g (T i).y₀ = 0) : f R.x₁ - f R.x₀ = 0 ∨ g R.y₁ - g R.y₀ = 0
theorem IntegerRectangle.StepFunction.dichotomy {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (f g : ℝ → ℝ) (htile : ∀ (i : ι), f (T i).x₁ - f (T i).x₀ = 0 ∨ g (T i).y₁ - g (T i).y₀ = 0) : f R.x₁ - f R.x₀ = 0 ∨ g R.y₁ - g R.y₀ = 0
**The step-function engine**: the fg-area dichotomy, for arbitrary `f, g : ℝ → ℝ`. If `T` tiles `R` and every tile has vanishing increment of `f` across its width or of `g` across its height, then the same dichotomy holds for `R`. This is the discrete counterpart of `IsTiling.prod_integral_dichotomy`.
The fg-area of every tile is a product with a vanishing factor, so by additivity of the fg-area
Lemma 7.33 the fg-area of R vanishes, and a product of reals vanishes only if
a factor does.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.35●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_StepFunction[complete]
-
IntegerRectangleTheorem_StepFunction[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/StepFunction.leancomplete
theorem IntegerRectangleTheorem_StepFunction : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_StepFunction : IntegerRectangleTheorem
**Step-function proof** (Hochster–Maté) of the integer-rectangle tiling theorem: the fg-area dichotomy for the sawtooth `Int.fract` in both coordinates.
Take f = g = \{\cdot\}, the sawtooth \{x\} = x - \lfloor x\rfloor — the identity minus a
step function. Its increment \{b\} - \{a\} vanishes if and only if b - a \in \mathbb{Z}, so a
tile with an integer side satisfies the hypothesis of the engine
Lemma 7.34, which returns a vanishing sawtooth increment for R in one
of the two directions — an integer side. The criterion is an exact "integer difference" statement,
so unlike the checkerboard proof, whose triangle wave is symmetric about the half-integers, this
argument needs no standard-position hypothesis. (The sawtooth increment is also the signed mass of
(a, b] under Lebesgue measure minus the counting measure of the integers, giving an alternative
measure-theoretic route to the additivity.)
Fourteenth proof: Sperner's lemma (Schmerl). Cut every tile in two along a diagonal and label each
vertex of the resulting figure by which of its coordinates are integers; a variation of Sperner's
lemma then makes the number of triangles carrying all three labels odd, and no tile with an
integer side has such a triangle. Following Mead, whose lemma this is, an edge is called
complete when its endpoints carry the first two labels, and a triangle is complete when its
vertices carry all three. The labelling is based at the corner of R rather than at the origin,
so the tiling is never translated.
Label points A, B or C, and call an edge complete when its endpoints are labelled A
and B. Counting modulo 2, the three sides of a triangle carry an odd number of complete
edges exactly when its three vertices carry three different labels.
Lean code for Lemma7.36●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Sperner.leancomplete
theorem IntegerRectangle.Sperner.completeEdge_sum_eq_one_iff (x y z : IntegerRectangle.Sperner.Color) : IntegerRectangle.Sperner.completeEdge x y + IntegerRectangle.Sperner.completeEdge y z + IntegerRectangle.Sperner.completeEdge z x = 1 ↔ IntegerRectangle.Sperner.IsCompleteTriple x y z
theorem IntegerRectangle.Sperner.completeEdge_sum_eq_one_iff (x y z : IntegerRectangle.Sperner.Color) : IntegerRectangle.Sperner.completeEdge x y + IntegerRectangle.Sperner.completeEdge y z + IntegerRectangle.Sperner.completeEdge z x = 1 ↔ IntegerRectangle.Sperner.IsCompleteTriple x y z
**The local count of Sperner's lemma in dimension two.** The three sides of a triangle carry an odd number of complete edges exactly when the triangle itself is complete. This is the step that turns a parity count of edges into a count of completely labelled triangles.
A finite check of the 27 labellings of an ordered triple.
Sperner's lemma in dimension one: a two-colouring of the points subdividing a segment has an odd number of complete edges exactly when the two ends of the segment are coloured differently.
Lean code for Lemma7.37●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Sperner.leancomplete
theorem IntegerRectangle.Sperner.odd_card_completeEdges_iff {p q : ℕ} (h : p ≤ q) (c : ℕ → ZMod 2) : Odd (IntegerRectangle.Sperner.completeEdges c p q).card ↔ c p ≠ c q
theorem IntegerRectangle.Sperner.odd_card_completeEdges_iff {p q : ℕ} (h : p ≤ q) (c : ℕ → ZMod 2) : Odd (IntegerRectangle.Sperner.completeEdges c p q).card ↔ c p ≠ c q
**Sperner's lemma in dimension one.** A two-colouring of the points subdividing a segment has an odd number of complete edges exactly when its two ends are coloured differently — however many points subdivide it.
Modulo 2 the colour increments along the segment telescope, so their sum is the sum of the two
ends; and an increment is 1 exactly on a complete edge, so that sum counts the complete edges.
The telescoped identity is the form the application below uses.
Label (x, y) by A if x differs from the abscissa of the corner of R by an integer, by
B if it does not but y differs from the ordinate by an integer, and by C otherwise. Then
the complete edges among the grid segments composing a horizontal side sum, modulo 2, to the
indicator of the side's own two endpoints.
Lean code for Lemma7.38●1 theorem
Associated Lean declarations
-
IntegerRectangle.Sperner.sum_segComplete[complete]
-
IntegerRectangle.Sperner.sum_segComplete[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Sperner.leancomplete
theorem IntegerRectangle.Sperner.sum_segComplete {ι : Type} [Fintype ι] (R : IntegerRectangle.Rectangle) (T : ι → IntegerRectangle.Rectangle) {p q : ℕ} (h : p ≤ q) (k : ℕ) : ∑ j ∈ Finset.Ico p q, IntegerRectangle.Sperner.segComplete R T j k = IntegerRectangle.Sperner.completeEdge (IntegerRectangle.Sperner.label (IntegerRectangle.Sperner.corner R) (IntegerRectangle.Grid.nth (IntegerRectangle.Grid.gridX R T) p, IntegerRectangle.Grid.nth (IntegerRectangle.Grid.gridY R T) k)) (IntegerRectangle.Sperner.label (IntegerRectangle.Sperner.corner R) (IntegerRectangle.Grid.nth (IntegerRectangle.Grid.gridX R T) q, IntegerRectangle.Grid.nth (IntegerRectangle.Grid.gridY R T) k))
theorem IntegerRectangle.Sperner.sum_segComplete {ι : Type} [Fintype ι] (R : IntegerRectangle.Rectangle) (T : ι → IntegerRectangle.Rectangle) {p q : ℕ} (h : p ≤ q) (k : ℕ) : ∑ j ∈ Finset.Ico p q, IntegerRectangle.Sperner.segComplete R T j k = IntegerRectangle.Sperner.completeEdge (IntegerRectangle.Sperner.label (IntegerRectangle.Sperner.corner R) (IntegerRectangle.Grid.nth (IntegerRectangle.Grid.gridX R T) p, IntegerRectangle.Grid.nth (IntegerRectangle.Grid.gridY R T) k)) (IntegerRectangle.Sperner.label (IntegerRectangle.Sperner.corner R) (IntegerRectangle.Grid.nth (IntegerRectangle.Grid.gridX R T) q, IntegerRectangle.Grid.nth (IntegerRectangle.Grid.gridY R T) k))
**The complete edges along a subdivided horizontal side are counted, modulo `2`, by its endpoints.** This is the variation of Sperner's lemma that Schmerl's proof needs: one diagonal per tile is not a triangulation in the usual sense, since a corner of one tile may lie inside an edge of another, so a side of a triangle carries however many vertices its neighbours put there. Along a horizontal line the labels record the integrality of the abscissa, so the complete edges on the side count the changes of that integrality — and the parity of the number of changes is fixed by the two ends.
This is the point of the geometric labelling, and what lets the argument run on a figure that is
not a triangulation in the usual sense: a corner of one tile may lie inside an edge of another, so
a side of a triangle carries however many vertices its neighbours put there, and its number of
complete edges is not determined by its endpoints. Its parity is. Along a horizontal segment the
ordinate is constant, so at an integer height the labels are A and B according to the
integrality of the abscissa, and at any other height they are A and C and no edge is
complete; in the first case a complete edge records a change in the integrality of the abscissa,
and a sequence has an odd number of changes exactly when its two ends differ
Lemma 7.37. Along a vertical segment the abscissa is constant, so either every
point is labelled A or none is, and no edge is ever complete.
Neither of the two triangles of a tile with an integer side is complete.
Lean code for Lemma7.39●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Sperner.leancomplete
theorem IntegerRectangle.Sperner.not_isCompleteTriangle (o : ℝ × ℝ) {S : IntegerRectangle.Rectangle} (hS : S.HasIntegerSide) (b : Bool) : ¬IntegerRectangle.Sperner.IsCompleteTriangle o S b
theorem IntegerRectangle.Sperner.not_isCompleteTriangle (o : ℝ × ℝ) {S : IntegerRectangle.Rectangle} (hS : S.HasIntegerSide) (b : Bool) : ¬IntegerRectangle.Sperner.IsCompleteTriangle o S b
**A tile with an integer side has no complete triangle.** If the width is an integer the two ends of each horizontal side agree in the integrality of their abscissa, hence in their label; if the height is an integer the two ends of each vertical side do. Either way both triangles of the tile have two vertices carrying the same label.
If the width of the tile is an integer, its left and right edges have abscissae differing by an integer, so the two ends of each of its horizontal sides carry the same label; if the height is an integer, the two ends of each of its vertical sides do. Either way each of the two triangles has two vertices with a common label, hence not three different ones.
Summed over all the triangles, the number of complete edges on their sides equals, modulo 2,
the number along the bottom and top edges of R.
Lean code for Lemma7.40●1 theorem
Associated Lean declarations
-
IntegerRectangle.Sperner.sum_tile_edges[complete]
-
IntegerRectangle.Sperner.sum_tile_edges[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Sperner.leancomplete
theorem IntegerRectangle.Sperner.sum_tile_edges {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {N : ℕ} (hN : ((IntegerRectangle.Grid.gridY R T).sort fun a b ↦ a ≤ b).length = N + 2) : ∑ i, ∑ j ∈ Finset.Ico (IntegerRectangle.Grid.idxL R T i) (IntegerRectangle.Grid.idxR R T i), (IntegerRectangle.Sperner.segComplete R T j (IntegerRectangle.Grid.idxB R T i) + IntegerRectangle.Sperner.segComplete R T j (IntegerRectangle.Grid.idxT R T i)) = ∑ j ∈ Finset.range (((IntegerRectangle.Grid.gridX R T).sort fun a b ↦ a ≤ b).length - 1), (IntegerRectangle.Sperner.segComplete R T j 0 + IntegerRectangle.Sperner.segComplete R T j (N + 1))
theorem IntegerRectangle.Sperner.sum_tile_edges {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {N : ℕ} (hN : ((IntegerRectangle.Grid.gridY R T).sort fun a b ↦ a ≤ b).length = N + 2) : ∑ i, ∑ j ∈ Finset.Ico (IntegerRectangle.Grid.idxL R T i) (IntegerRectangle.Grid.idxR R T i), (IntegerRectangle.Sperner.segComplete R T j (IntegerRectangle.Grid.idxB R T i) + IntegerRectangle.Sperner.segComplete R T j (IntegerRectangle.Grid.idxT R T i)) = ∑ j ∈ Finset.range (((IntegerRectangle.Grid.gridX R T).sort fun a b ↦ a ≤ b).length - 1), (IntegerRectangle.Sperner.segComplete R T j 0 + IntegerRectangle.Sperner.segComplete R T j (N + 1))
**The complete edges of all the triangles are those on the bottom and top edges of `R`.** The column count, summed over the columns of the grid.
The diagonal of a tile is a side of both of its triangles, so it is counted twice and cancels, and
its vertical sides carry no complete edge Lemma 7.38; what is left of a
tile is the complete edges on its bottom and top edges. Refine the tiling to its grid: every open
grid cell lies in a unique tile Lemma 7.33, so along a fixed column of cells a
horizontal grid segment strictly inside R either has the same tile above and below it, and is
interior to that tile and counted by neither of its triangles, or has different tiles, and is then
the top edge of the lower and the bottom edge of the upper and counted exactly twice. Everything
in the interior of the column therefore cancels, leaving the segment at the bottom of the column
and the one at the top; summing over the columns leaves the bottom and top edges of R.
The variation of Sperner's lemma, as Wagon uses it. If neither side of R is an integer,
the number of complete triangles is odd.
Lean code for Lemma7.41●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Sperner.leancomplete
theorem IntegerRectangle.Sperner.odd_card_completeTriangles {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hw : ¬∃ n, R.width = ↑n) (hh : ¬∃ n, R.height = ↑n) : Odd {t | IntegerRectangle.Sperner.IsCompleteTriangle (IntegerRectangle.Sperner.corner R) (T t.1) t.2}.card
theorem IntegerRectangle.Sperner.odd_card_completeTriangles {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hw : ¬∃ n, R.width = ↑n) (hh : ¬∃ n, R.height = ↑n) : Odd {t | IntegerRectangle.Sperner.IsCompleteTriangle (IntegerRectangle.Sperner.corner R) (T t.1) t.2}.card
**The number of completely labelled triangles is odd**, when neither side of `R` is an integer. This is the conclusion Wagon draws from his variation of Sperner's lemma, and the whole weight of the proof: each triangle contributes its parity of complete edges (`sideCount_eq_ite`), the tiles' contributions are the complete edges on their bottom and top edges (`sum_sideCount`), the interior horizontal segments pair off (`sum_tile_edges`), and what survives is the bottom edge of `R` — a single complete edge, since the corner of `R` is labelled `A` and its lower-right corner `B` — together with its top edge, which carries none because the height of `R` is not an integer.
Each triangle carries an odd number of complete edges exactly when it is itself complete
Lemma 7.36, so modulo 2 the number of complete triangles is the
total number of complete edges over all the triangles, which is the number along the bottom and
top edges of R Lemma 7.40. The top edge is at a height differing
from the bottom by the height of R, not an integer, so it carries none. The bottom edge runs
at an integer height from the corner of R, labelled A, to its lower-right corner, labelled
B because the width of R is not an integer — so it carries a single one
Lemma 7.38. The total is therefore odd.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.42●1 theorem
Associated Lean declarations
-
IntegerRectangleTheorem_Sperner[complete]
-
IntegerRectangleTheorem_Sperner[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Sperner.leancomplete
theorem IntegerRectangleTheorem_Sperner : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_Sperner : IntegerRectangleTheorem
**Sperner's lemma proof** (Schmerl) of the integer-rectangle tiling theorem, in the two steps Wagon states it: if neither side of `R` were an integer, the number of triangles labelled `ABC` would be odd (`odd_card_completeTriangles`), and in particular there would be one; but every tile has an integer side, so no triangle is so labelled (`not_isCompleteTriangle`).
Suppose neither side of R is an integer. Then the number of complete triangles is odd
Lemma 7.41, and in particular there is one. But every tile has an integer
side, so neither of its triangles is complete Lemma 7.39 — a
contradiction.