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 of positive width and height 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/Tiling/Integral.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.
Wagon's fourth, fifth and sixth proofs each build an auxiliary tiling by moving the lines of the given one without changing their order, and compare a count or an area over the two tilings. They rest on three facts about tilings.
The half-open cells of the tiles of a tiling — each tile with its left and bottom edges removed — are pairwise disjoint, and their union is the half-open cell of the tiled rectangle.
Lean code for Lemma7.6●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Tiling/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.
The areas of the tiles of a tiling add up to the area of the tiled rectangle.
Lean code for Lemma7.7●1 theorem
Associated Lean declarations
-
IntegerRectangle.IsTiling.sum_area[complete]
-
IntegerRectangle.IsTiling.sum_area[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Tiling/Basic.leancomplete
theorem IntegerRectangle.IsTiling.sum_area {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : ∑ i, (T i).area = R.area
theorem IntegerRectangle.IsTiling.sum_area {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : ∑ i, (T i).area = R.area
**Area is additive over a tiling**: Lebesgue measure is.
The area of a rectangle is the Lebesgue measure of its half-open cell, and the half-open cells of the tiles partition that of the tiled rectangle Lemma 7.6.
Let T tile R, and move every vertical line x = a of the tiling to x = \varphi(a) and
every horizontal line y = b to y = \psi(b), by maps \varphi and \psi keeping the order
of the abscissae of the vertical lines and of the ordinates of the horizontal ones. If R does
not collapse, the moved tiles that do not collapse to segments tile the moved R.
Lean code for Lemma7.8●1 theorem
Associated Lean declarations
-
IntegerRectangle.IsTiling.image[complete]
-
IntegerRectangle.IsTiling.image[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Tiling/Image.leancomplete
theorem IntegerRectangle.IsTiling.image {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {φ ψ : ℝ → ℝ} (hT : IntegerRectangle.IsTiling R T) (hφ : MonotoneOn φ ↑(IntegerRectangle.Grid.gridX R T)) (hψ : MonotoneOn ψ ↑(IntegerRectangle.Grid.gridY R T)) (hx : φ R.x₀ < φ R.x₁) (hy : ψ R.y₀ < ψ R.y₁) : IntegerRectangle.IsTiling (IntegerRectangle.Rectangle.image φ ψ R) (IntegerRectangle.prune fun i ↦ IntegerRectangle.Rectangle.image φ ψ (T i))
theorem IntegerRectangle.IsTiling.image {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {φ ψ : ℝ → ℝ} (hT : IntegerRectangle.IsTiling R T) (hφ : MonotoneOn φ ↑(IntegerRectangle.Grid.gridX R T)) (hψ : MonotoneOn ψ ↑(IntegerRectangle.Grid.gridY R T)) (hx : φ R.x₀ < φ R.x₁) (hy : ψ R.y₀ < ψ R.y₁) : IntegerRectangle.IsTiling (IntegerRectangle.Rectangle.image φ ψ R) (IntegerRectangle.prune fun i ↦ IntegerRectangle.Rectangle.image φ ψ (T i))
**Moving the lines of a tiling in order gives a tiling.** If `φ` and `ψ` are monotone on the coordinates of the vertical and the horizontal lines of a tiling of `R`, and the image of `R` is not degenerate, then the images of the tiles, those that collapse pruned, tile the image of `R`. The moved tiles lie in the moved rectangle, and every point `z` pulls back to a point that lies in the half-open cell of a tile, or of `R`, exactly when `z` lies in that of its image. So the half-open cells of the moved tiles inherit from those of the tiles that they are pairwise disjoint and cover (`IsTiling.pairwiseDisjoint_toSetIoc`, `IsTiling.iUnion_toSetIoc`), which makes the moved tiles a tiling once the collapsed ones are pruned (`isTiling_prune_of_toSetIoc`).
By half-open cells Lemma 7.6. Pull a point z back to the point whose
abscissa is the leftmost vertical line of the tiling whose image is not to the left of z, or a
point beyond the tiling if there is none, and whose ordinate is the lowest horizontal line whose
image is not below z. Since the moves keep the order of the lines, this point lies in the
half-open cell of a tile, or of R, exactly when z lies in that of its image. So the
half-open cells of the moved tiles are pairwise disjoint and cover the half-open cell of the moved
R, because those of the tiling are and do; a tile collapsed to a segment has an empty half-open
cell and is discarded.
Fourth proof: counting squares (Ruzsa, Gilbert). Place R in standard position and translate
every vertical line of the tiling with a noninteger abscissa a to the half-integer line
x = \lfloor a\rfloor + \tfrac12, and likewise the horizontal lines, the integral lines staying
put. Here the lattice is based at the lower-left corner of R, which replaces the standard
position. The translated tiles tile a translated rectangle all of whose coordinates lie 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.
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.9●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 translated tiles contain, in all, as many half-unit squares as the translated rectangle, and a translated rectangle contains as many squares as the product of the increments of the two grid coordinates across it.
Lean code for Lemma7.10●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) : ∑ i, IntegerRectangle.CountingSquares.cellCount R.x₀ R.y₀ (T i) = IntegerRectangle.CountingSquares.cellCount R.x₀ R.y₀ R
theorem IntegerRectangle.CountingSquares.sum_cellCount {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : ∑ i, IntegerRectangle.CountingSquares.cellCount R.x₀ R.y₀ (T i) = IntegerRectangle.CountingSquares.cellCount R.x₀ R.y₀ R
**The squares of `R'` are those of its tiles.** The translated tiles tile the translated rectangle `R'` (`IsTiling.image`), and every square of `R'` lies in exactly one of them (`card_squares_eq_sum`); a tile collapsed by the translation has no square.
The translation keeps the order of the lines, so the translated tiles tile the translated
rectangle Lemma 7.8. Count the squares by their upper right corners: a
square lies in a rectangle whose edges are grid lines exactly when its upper right corner lies in
the half-open cell of the rectangle, so every square of the translated rectangle lies in exactly
one translated tile Lemma 7.6, and a rectangle whose edges are the grid
lines c_0 \le c_1 and d_0 \le d_1 half-steps from the corner of R contains
(c_1 - c_0)(d_1 - d_0) squares.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.11●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, so its translation contains an even number of squares, and therefore so does the translation of `R`. The corner of `R` has grid coordinate `0`, so the square count of the translation 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.
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 translated tile
contains an even number of squares, and hence Lemma 7.10 so does the
translated rectangle. 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.9 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). With the lattices again based at the lower-left corner of R
and a parameter t, move a vertical line of the tiling by t when its abscissa is off the
lattice and a horizontal line by t when its ordinate is, leaving the lattice lines fixed. For
t smaller than the least gap between the lines of the tiling the moved lines keep their order,
and the areas of the moved rectangles are polynomials in t.
As a polynomial in t, the area of the moved R is the sum of the areas of the moved tiles.
Lean code for Lemma7.12●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Polynomials.leancomplete
theorem IntegerRectangle.Polynomials.sum_areaPoly {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : ∑ i, IntegerRectangle.Polynomials.areaPoly R.x₀ R.y₀ (T i) = IntegerRectangle.Polynomials.areaPoly R.x₀ R.y₀ R
theorem IntegerRectangle.Polynomials.sum_areaPoly {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : ∑ i, IntegerRectangle.Polynomials.areaPoly R.x₀ R.y₀ (T i) = IntegerRectangle.Polynomials.areaPoly R.x₀ R.y₀ R
**The area of `R'` is the sum of the areas of its tiles, as polynomials.** For every `t` in an interval `[0, δ)` the translated tiles tile the translated rectangle, whose area is therefore the sum of theirs (`IsTiling.sum_area_image`), and two polynomials agreeing at infinitely many points are equal.
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_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 area of each translated tile is linear or constant in the parameter `t`, while a tiled rectangle with no integer side would have a genuinely quadratic one; comparing `X ^ 2` coefficients in the polynomial identity given by the additivity of area gives `0 = 1`.
Let \varepsilon_x(u) be 0 when u - R_x \in \mathbb{Z} and 1 otherwise, and similarly
define \varepsilon_y, so that the lines move by \varphi_t(u) = u + t\varepsilon_x(u) and
\psi_t(v) = v + t\varepsilon_y(v). The area of a moved rectangle S is 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. 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 area of the moved tile is linear or constant
in t, and hence Lemma 7.12 so is the area of the moved R. If neither
side of R is an integer, each lower endpoint has indicator 0 and each upper endpoint 1, so
the moved R is (w + t) \times (h + t) and its area has quadratic coefficient 1, a
contradiction.
Sixth proof: prime numbers (Robinson). For a prime p, scale the tiling by p and replace every
tile corner (x, y) of the scaled tiling by (\lfloor x\rfloor, \lfloor y\rfloor). This moves
the vertical line x = a to x = \lfloor pa\rfloor and the horizontal line y = b to
y = \lfloor pb\rfloor, keeping their order, so the rounded tiles tile the rounded rectangle, an
integer-sided rectangle tiled by integer-sided rectangles; a tile narrower or lower than 1/p may
collapse to a segment and drop out.
If every tile has an integer side and the rounded rectangle does not collapse, its area is a
multiple of p.
Lean code for Lemma7.14●1 theorem
Associated Lean declarations
-
IntegerRectangle.Primes.dvd_area_round[complete]
-
IntegerRectangle.Primes.dvd_area_round[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Primes.leancomplete
theorem IntegerRectangle.Primes.dvd_area_round {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) {p : ℕ} (hx : ⌊R.x₀ * ↑p⌋ < ⌊R.x₁ * ↑p⌋) (hy : ⌊R.y₀ * ↑p⌋ < ⌊R.y₁ * ↑p⌋) : ↑p ∣ (⌊R.x₁ * ↑p⌋ - ⌊R.x₀ * ↑p⌋) * (⌊R.y₁ * ↑p⌋ - ⌊R.y₀ * ↑p⌋)
theorem IntegerRectangle.Primes.dvd_area_round {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) {p : ℕ} (hx : ⌊R.x₀ * ↑p⌋ < ⌊R.x₁ * ↑p⌋) (hy : ⌊R.y₀ * ↑p⌋ < ⌊R.y₁ * ↑p⌋) : ↑p ∣ (⌊R.x₁ * ↑p⌋ - ⌊R.x₀ * ↑p⌋) * (⌊R.y₁ * ↑p⌋ - ⌊R.y₀ * ↑p⌋)
**The area of the rounded rectangle is a multiple of `p`.** The rounded tiles tile the rounded rectangle, and each has a side whose length is a multiple of `p`, since a side of integer length `n` rounds to one of length `p n`.
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.15●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 side of the rounded rectangle is a multiple of `p` (`dvd_area_round`), or is `0`.
The sides of the rounded rectangle are integers that differ from those of the scaled-up rectangle
by less than 1. If one of them is 0, the corresponding side of R is shorter than 1/p.
Otherwise the area of the rounded rectangle is a multiple of p Lemma 7.14,
and p being prime, so is one of its sides, 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.16●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. If neither side of `R` were an integer, then for all large `p` neither would be within `1/p` of an integer; there are infinitely many primes, and a large one contradicts Wagon's claim (`exists_side_near_int`).
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.15 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.
The formalization builds \Gamma as a multigraph through its half-edges, or darts, a dart being a
tile together with one of its four corners. Each tile contributes its two horizontal sides if its
width is an integer and its two vertical sides otherwise, and the two darts of such a side are its
two ends. Two tiles of the same integer width stacked on each other share a side, which is then a
double edge of \Gamma. The degree of a vertex is the number of darts at it, which is the number
of tiles having it as a corner.
Of the degrees only the parity is ever used, and Wagon reads it off the local picture of how the
tiles fit together around a point, which the eighth proof shares. Nor is the walk built step by
step: what makes it reach a second corner of R is the handshake lemma, which stands in for it
here since mathlib's multigraphs have no walks yet.
Let T tile R. At a corner of R the tiles have exactly one corner in all, and at any other
point of the plane none, two or four. (Each rectangle has four corners, counted with
multiplicity.)
Lean code for Lemma7.17●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/Tiling/CornerCount.leancomplete
theorem IntegerRectangle.IsTiling.sum_cornerCount_eq {ι : 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 ∨ IntegerRectangle.cornerCount R u v = 0 ∧ (∑ i, IntegerRectangle.cornerCount (T i) u v = 2 ∨ ∑ i, IntegerRectangle.cornerCount (T i) u v = 4)
theorem IntegerRectangle.IsTiling.sum_cornerCount_eq {ι : 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 ∨ IntegerRectangle.cornerCount R u v = 0 ∧ (∑ i, IntegerRectangle.cornerCount (T i) u v = 2 ∨ ∑ i, IntegerRectangle.cornerCount (T i) u v = 4)
**The local picture at a point** (Wagon). At a corner of `R` the tiles have exactly one corner in all, and at any other point of the plane `0`, `2` or `4`. Counted over the tiles, the quadrants filled at the point are the quadrants inside `R` (`IsTiling.sum_card_quadrants`): four, two, one or none, according as the point lies inside `R`, inside one of its edges, at one of its corners, or outside it. A tile having the point as a corner fills one of them, and any other tile none, two or four (`cornerCount_eq_ite`), so the tiles having the point as a corner are at most as many as the quadrants inside `R`, and as many up to an even number.
Look at the four quadrants at the point. A tile containing the point fills one of them if the
point is a corner of the tile, two if the point lies inside one of its edges, and four if it lies
inside the tile. Each quadrant inside R is filled by exactly one tile, so the numbers of
quadrants the tiles fill add up to the number of quadrants inside R: four at a point inside
R, two at a point inside one of its edges, one at a corner, and none outside R. The tiles
having the point as a corner fill one quadrant each and the other tiles an even number, so the
former are at most as many as the quadrants inside R, and as many up to an even number.
In a finite multigraph, a vertex of odd degree is joined by a walk to another vertex of odd degree.
Lean code for Lemma7.18●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofsForMathlib/Combinatorics/Graph/HalfEdgePairing.leancomplete
theorem HalfEdgePairing.exists_ne_reflTransGen_of_odd.{u_1, u_2, u_3} {E : Type u_1} {D : Type u_2} {W : Type u_3} (P : HalfEdgePairing E D) [Finite D] (lab : D → W) {x : W} (hx : Odd (Nat.card { d // lab d = x })) : ∃ y, y ≠ x ∧ Relation.ReflTransGen (P.labelGraph lab).Adj x y ∧ Odd (Nat.card { d // lab d = y })
theorem HalfEdgePairing.exists_ne_reflTransGen_of_odd.{u_1, u_2, u_3} {E : Type u_1} {D : Type u_2} {W : Type u_3} (P : HalfEdgePairing E D) [Finite D] (lab : D → W) {x : W} (hx : Odd (Nat.card { d // lab d = x })) : ∃ y, y ≠ x ∧ Relation.ReflTransGen (P.labelGraph lab).Adj x y ∧ Odd (Nat.card { d // lab d = y })
**A vertex of odd degree is joined to another one.** A label carried by an odd number of half-edges is joined by a chain of edges of `labelGraph lab` to a different label carried by an odd number of half-edges: by the handshake lemma, the labels it reaches carry evenly many half-edges in all.
The vertices that walks from it reach form a union of connected components, so every edge at one of them has both of its ends among them, and their degrees add up to twice the number of these edges. That sum is even, so besides the degree of the starting vertex another of its terms is odd.
Let T tile R. Then some walk in \Gamma leads from the lower-left corner of R to another
corner of R.
Lean code for Lemma7.19●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/EulerianPath.leancomplete
theorem IntegerRectangle.EulerianPath.exists_reachable_corner {ι : Type} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] {R : IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : Relation.ReflTransGen (IntegerRectangle.EulerianPath.patersonGraph T).Adj (R.x₀, R.y₀) (R.x₁, R.y₀) ∨ Relation.ReflTransGen (IntegerRectangle.EulerianPath.patersonGraph T).Adj (R.x₀, R.y₀) (R.x₀, R.y₁) ∨ Relation.ReflTransGen (IntegerRectangle.EulerianPath.patersonGraph T).Adj (R.x₀, R.y₀) (R.x₁, R.y₁)
theorem IntegerRectangle.EulerianPath.exists_reachable_corner {ι : Type} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] {R : IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) : Relation.ReflTransGen (IntegerRectangle.EulerianPath.patersonGraph T).Adj (R.x₀, R.y₀) (R.x₁, R.y₀) ∨ Relation.ReflTransGen (IntegerRectangle.EulerianPath.patersonGraph T).Adj (R.x₀, R.y₀) (R.x₀, R.y₁) ∨ Relation.ReflTransGen (IntegerRectangle.EulerianPath.patersonGraph T).Adj (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 is a vertex of odd degree, so the handshake lemma joins it to another vertex of odd degree, and that is a corner of `R`.
The degree of a vertex is the number of tiles having it as a corner, so by the local picture
Lemma 7.17 the vertices of odd degree are the corners of R. The
lower-left corner is one of them, and by the handshake lemma Lemma 7.18 a walk leads
from it to another vertex of odd degree, which is another corner of R.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.20●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.19 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, let S be the set of corners of tiles having both coordinates integers, and form the
bipartite graph on S and the set of tiles that joins each point of S to all the tiles of which
it is a corner. Its edges are counted in the two possible ways. The formalization builds this
graph as a mathlib multigraph whose edges are the incidences of the tiles with their corners, and
cuts S out by the lattice through the lower-left corner of R, which replaces the standard
position.
In a bipartite multigraph with finitely many edges, the numbers of edges at the vertices of one part add up to the same total as the numbers of edges at the vertices of the other part.
Lean code for Lemma7.21●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofsForMathlib/Combinatorics/Graph/Bipartite.leancomplete
theorem Graph.IsBipartiteWith.sum_ncard_incidenceSet_eq.{u_1, u_2} {α : Type u_1} {β : Type u_2} {G : Graph α β} {s t : Finset α} (h : G.IsBipartiteWith ↑s ↑t) (hE : G.edgeSet.Finite) : ∑ x ∈ s, (Graph.incidenceSet x).ncard = ∑ y ∈ t, (Graph.incidenceSet y).ncard
theorem Graph.IsBipartiteWith.sum_ncard_incidenceSet_eq.{u_1, u_2} {α : Type u_1} {β : Type u_2} {G : Graph α β} {s t : Finset α} (h : G.IsBipartiteWith ↑s ↑t) (hE : G.edgeSet.Finite) : ∑ x ∈ s, (Graph.incidenceSet x).ncard = ∑ y ∈ t, (Graph.incidenceSet y).ncard
**Counting the edges of a bipartite multigraph from either side.** The numbers of edges at the vertices of `s` and at the vertices of `t` have the same sum, the number of edges.
Every edge has exactly one end in each part, so either sum counts every edge exactly once.
A tile with an integer side has 0, 2 or 4 corners in S, so evenly many edges.
Lean code for Lemma7.22●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/BipartiteGraph.leancomplete
theorem IntegerRectangle.BipartiteGraph.even_ncard_incidenceSet_inr {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {i : ι} (h : (T i).HasIntegerSide) : Even (Graph.incidenceSet (Sum.inr i)).ncard
theorem IntegerRectangle.BipartiteGraph.even_ncard_incidenceSet_inr {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} {i : ι} (h : (T i).HasIntegerSide) : Even (Graph.incidenceSet (Sum.inr i)).ncard
**A tile with an integer side has `0`, `2` or `4` corners on the lattice**, so evenly many edges: the two ends of a side of integer length have coordinates with the same fractional parts, so they are on the lattice together or not at all.
The two ends of a side of integer length are both on the lattice or neither is, so the corners of the tile on the lattice come in pairs, the two ends of the same side.
Let T tile R by tiles with an integer side. Then some point of S other than the
lower-left corner of R lies on an odd number of tiles.
Lean code for Lemma7.23●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/BipartiteGraph.leancomplete
theorem IntegerRectangle.BipartiteGraph.exists_odd {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : ∃ z ∈ IntegerRectangle.BipartiteGraph.latticeCorners R T, z ≠ (R.x₀, R.y₀) ∧ Odd (∑ i, IntegerRectangle.cornerCount (T i) z.1 z.2)
theorem IntegerRectangle.BipartiteGraph.exists_odd {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : ∃ z ∈ IntegerRectangle.BipartiteGraph.latticeCorners R T, z ≠ (R.x₀, R.y₀) ∧ Odd (∑ i, IntegerRectangle.cornerCount (T i) z.1 z.2)
**Another point of `S` lies on an odd number of tiles.** Counted from the side of the tiles, the edges of the bipartite graph are evenly many. Counted from the side of `S` they are the numbers of tiles the points of `S` lie on, and the lower-left corner of `R` lies on only one.
Counted from the side of the tiles, the edges of the graph are evenly many
Lemma 7.22, so by the count from the other side
Lemma 7.21 the numbers of tiles the points of S lie on have an even
sum. The lower-left corner of R lies on exactly one tile Lemma 7.17,
so it is in S, and the numbers for the other points of S have an odd sum.
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_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. Another point of `S` lies on an odd number of tiles (`exists_odd`); a point that is not a corner of `R` lies on none, two or four, so it is another corner of `R`, and being on the lattice it makes a side of `R` an integer.
Take a point of S other than the lower-left corner of R lying on an odd number of tiles
Lemma 7.23. A point that is not a corner of R lies on none, two or
four tiles Lemma 7.17, so this one is another corner of R, and being
on the lattice through the lower-left corner it is an integer width or height away from it.
The two inductive proofs that follow treat as immediate the case of a tiling all of whose tiles have integer width, or all of whose tiles have integer height. It is settled by slicing the tiling along a line, the geometric ingredient of the twelfth proof 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.25●1 theorem
Associated Lean declarations
-
IntegerRectangle.widthSum_slice[complete]
-
IntegerRectangle.widthSum_slice[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Tiling/Slice.leancomplete
theorem IntegerRectangle.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.edgeSet T) : (IntegerRectangle.widthSum T fun i ↦ (T i).y₀ < t ∧ t < (T i).y₁) = R.width
theorem IntegerRectangle.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.edgeSet T) : (IntegerRectangle.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 horizontal tile edge: the widths of the tiles the line crosses add up to the width of the tiled rectangle. Length along the line, the measure `volume.prod (Measure.dirac t)`, adds up over the half-open cells of the tiles, like every measure (`IsTiling.measure_toSetIoc`). The line meets the cell of a tile, in an interval of the tile's width, exactly when it crosses the tile, as `t` is not a top edge; and it meets the cell of `R` in an interval of the full width, as it is not the bottom edge of `R` either: the tile containing `(R.x₀, t)` reaches below it.
Length along the line y = t is a measure on the plane, so it adds up over the half-open cells of
the tiles, which partition that of R Lemma 7.6. Because t avoids the
horizontal edges, the line meets the half-open cell of a tile, in an interval as long as the tile
is wide, exactly when it crosses the tile; and it meets the half-open cell of R in an interval
of the full width, since it is not the bottom edge of R: the tile containing the point of the
left edge of R at height t reaches below it.
-
IntegerRectangle.intWidth_of_forall[complete] -
IntegerRectangle.intHeight_of_forall[complete]
If every tile of a tiling of R has integer width, then so has R; and likewise for heights.
Lean code for Lemma7.26●2 theorems
Associated Lean declarations
-
IntegerRectangle.intWidth_of_forall[complete]
-
IntegerRectangle.intHeight_of_forall[complete]
-
IntegerRectangle.intWidth_of_forall[complete] -
IntegerRectangle.intHeight_of_forall[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Tiling/Slice.leancomplete
theorem IntegerRectangle.intWidth_of_forall {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (h : ∀ (i : ι), (T i).IsHTile) : R.IsHTile
theorem IntegerRectangle.intWidth_of_forall {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (h : ∀ (i : ι), (T i).IsHTile) : R.IsHTile
**A tiling by H-tiles tiles a rectangle of integer width.** A horizontal line through `R` missing the horizontal edges of the tiles crosses tiles of integer width, which span the width of `R` (`widthSum_slice`).
-
theoremdefined in DifferentProofs/IntegerRectangle/Tiling/Slice.leancomplete
theorem IntegerRectangle.intHeight_of_forall {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (h : ∀ (i : ι), (T i).IsVTile) : R.IsVTile
theorem IntegerRectangle.intHeight_of_forall {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (h : ∀ (i : ι), (T i).IsVTile) : R.IsVTile
**A tiling by V-tiles tiles a rectangle of integer height**: transposed, it is a tiling by H-tiles.
A horizontal line through R avoiding the finitely many heights of horizontal tile edges crosses
tiles whose widths add up to the width of R Lemma 7.25, and these widths are
integers. For heights, transpose the tiling.
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.27●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) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : IntegerRectangle.Staircase.Normalized R (IntegerRectangle.Staircase.pieceTiles T) (IntegerRectangle.Staircase.PieceIsHTile T)
theorem IntegerRectangle.IsTiling.normalized {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : IntegerRectangle.Staircase.Normalized R (IntegerRectangle.Staircase.pieceTiles T) (IntegerRectangle.Staircase.PieceIsHTile 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.
Cut each 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 has positive width and height. 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.28●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.29●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.28
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.30●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 ⋯) (IntegerRectangle.prune 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 ⋯) (IntegerRectangle.prune 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. Every tile leaves at least one degenerate piece, and a tile inside the strip leaves only degenerate ones; they are pruned.
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.29 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. Pieces of zero width have empty cells and are discarded; a tile inside the strip leaves only such pieces.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.31●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.27 and induct on the number of its H-tiles.
With no H-tile every tile has integer height, hence so does R
Lemma 7.26. Otherwise grow the staircase
from an H-tile Lemma 7.29. 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.30: 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.32●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) (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) (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, once the tiles
squeezed to zero width are discarded.
Lean code for Lemma7.33●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) {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.prune (IntegerRectangle.ReducibleLink.push l w ⋯ hR))
theorem IntegerRectangle.ReducibleLink.isTiling_push {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {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.prune (IntegerRectangle.ReducibleLink.push l w ⋯ hR))
**Pushing the tiles on the left of a link rightwards again tiles the same rectangle**, once the tiles on its right squeezed to nothing are discarded. 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.32, 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. A tile squeezed to zero
width has an empty cell, so discarding it changes nothing.
In a tiling with at least one H-tile and at least one V-tile, some link is reducible.
Lean code for Lemma7.34●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) {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) {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.35●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. If every tile has integer width, or every tile integer height, the fg-area settles the matter at once; 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. If every tile has integer width then so has R, and if every tile
has integer height then so has R Lemma 7.26. Otherwise some link is reducible
Lemma 7.34, 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.33. 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.
Eleventh proof: a minimal cut-set (Paul Seymour, Bell Communications Research). Form a graph
\Gamma: its vertices are the horizontal segments of the tiling, and its edges are the tiles —
each tile joins the segment carrying its bottom edge to the segment carrying its top edge — plus
one exterior edge running around the outside of R from its bottom edge to its top edge.
Drawing each edge up the vertical bisector of its tile embeds \Gamma in the plane, and the
faces of the embedding are the V-links of the tenth proof together with the two outer faces on
either side of the exterior edge. Call a tile a V-tile when its height is an integer, an H-tile
(of integer width) otherwise, and let S collect the H-tile edges together with the exterior
edge. If deleting S leaves the bottom of R connected to its top, a path of V-tiles climbs
from bottom to top and the height of R is an integer. Otherwise Seymour passes to a minimal
S' \subseteq S cutting the bottom off from the top and invokes a well-known theorem for planar
graphs: the duals of its edges form a cycle in the dual graph \Gamma^*. The cycle must use the
dual of the exterior edge — that edge alone joins bottom to top — and deleting it leaves a dual
path from the left outer face to the right one whose steps cross H-tiles, so the width of R is
an integer.
The formalization builds the embedding as the rotation system the drawing determines: the darts are the two ends of each edge, and the rotation turns each dart counterclockwise round its segment. A rotation system is planar when it is connected and its Euler characteristic is two, and the well-known theorem is proved for planar rotation systems in general.
In a planar combinatorial map, the edges of a bond of the graph, a minimal nonempty edge cut, form a cycle of the dual graph.
Lean code for Theorem7.36●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofsForMathlib/Combinatorics/Graph/CombinatorialMap.leancomplete
theorem CombinatorialMap.IsPlanar.isCycle_of_isBond.{u_1, u_2, u_3, u_4} {V : Type u_1} {E : Type u_2} {F : Type u_3} {D : Type u_4} {M : CombinatorialMap V E F D} [Finite D] (hM : M.IsPlanar) {B : Set E} (hB : M.graph.IsBond B) : M.dualGraph.IsCycle B
theorem CombinatorialMap.IsPlanar.isCycle_of_isBond.{u_1, u_2, u_3, u_4} {V : Type u_1} {E : Type u_2} {F : Type u_3} {D : Type u_4} {M : CombinatorialMap V E F D} [Finite D] (hM : M.IsPlanar) {B : Set E} (hB : M.graph.IsBond B) : M.dualGraph.IsCycle B
**Planar duality for bonds**: in a planar map, the edges of a bond of the graph, a minimal nonempty edge cut, form a cycle of the dual graph. A bond is even in the dual graph, and so is any smaller nonempty edge set meeting every face evenly, which by planarity is an edge cut; so a bond is a minimal nonempty even edge set of the dual graph, that is, a cycle of it.
Over \mathbb{Z}/2, the edge cuts of the graph form the image of its coboundary, and the edge
sets meeting every face evenly form the kernel of the boundary of the dual graph. The image lies
in the kernel, since walking round a face crosses an edge cut an even number of times, and the
two have dimensions \#V - 1 and \#E - \#F + 1, which Euler's formula makes equal. So a bond
is a minimal nonempty edge set meeting every face evenly. Such a set is a cycle: the rest of it
joins the two ends of any of its edges, by the handshake lemma Lemma 7.18, since
those two ends are the only faces it meets an odd number of times, and a shortest such path closes
up with the edge to a cycle which, being even, is all of it.
The vertices of the rotation system are the horizontal segments: the darts at a segment form one orbit of the rotation.
Lean code for Lemma7.37●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CutSet.leancomplete
theorem IntegerRectangle.CutSet.sameCycle_of_vert_eq {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {d d' : IntegerRectangle.CutSet.Dart ι} (h : IntegerRectangle.CutSet.vert hT d = IntegerRectangle.CutSet.vert hT d') : (IntegerRectangle.CutSet.rotPerm hT).SameCycle d d'
theorem IntegerRectangle.CutSet.sameCycle_of_vert_eq {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {d d' : IntegerRectangle.CutSet.Dart ι} (h : IntegerRectangle.CutSet.vert hT d = IntegerRectangle.CutSet.vert hT d') : (IntegerRectangle.CutSet.rotPerm hT).SameCycle d d'
**The darts at a vertex form one orbit of the rotation**: the vertices of the rotation system are exactly the horizontal segments.
Along the tiles below a segment the rotation passes from each tile to the next one on the right for as long as the segment goes on, then round the right end of the segment to the tiles above it, along which it moves left, and round the left end back below.
The faces of the rotation system are the V-links and the two outer faces.
Lean code for Lemma7.38●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CutSet.leancomplete
theorem IntegerRectangle.CutSet.sameCycle_of_faceOf_eq {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {d d' : IntegerRectangle.CutSet.Dart ι} (h : IntegerRectangle.CutSet.faceOf hT d = IntegerRectangle.CutSet.faceOf hT d') : (IntegerRectangle.CutSet.facePerm hT).SameCycle d d'
theorem IntegerRectangle.CutSet.sameCycle_of_faceOf_eq {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {d d' : IntegerRectangle.CutSet.Dart ι} (h : IntegerRectangle.CutSet.faceOf hT d = IntegerRectangle.CutSet.faceOf hT d') : (IntegerRectangle.CutSet.facePerm hT).SameCycle d d'
**The darts of a face form one orbit of the face permutation**: the faces of the rotation system are exactly the V-links and the two outer faces.
Following a dart to the other end of its edge and turning there stays on the V-link carrying the
corresponding vertical edge of the tile, because the corners the rotation turns round inside a
V-link are not blocked. Round a V-link the face permutation climbs its left side tile by tile
Lemma 7.32, crosses its top end to the right side, and descends that side;
round the outer faces it runs along the left and right edges of R and the exterior edge.
The embedding of Seymour's graph is planar.
Lean code for Lemma7.39●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CutSet.leancomplete
theorem IntegerRectangle.CutSet.seymourMap_isPlanar {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) : (IntegerRectangle.CutSet.seymourMap hT).IsPlanar
theorem IntegerRectangle.CutSet.seymourMap_isPlanar {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) : (IntegerRectangle.CutSet.seymourMap hT).IsPlanar
**Seymour's graph, embedded by the tiling, is planar**: its Euler characteristic is `2`.
The graph is connected, every segment being joined to the bottom of R through the tiles
below it. An edge set meeting every face evenly is an edge cut: colour each segment by the parity
of the tiles of the set stacked under it. The colour does not depend on where along the segment it
is read, because the tiles a moving column gains and loses abut V-links lying wholly below the
segment, each met evenly Lemma 7.38; crossing a tile changes the colour
exactly when the tile is in the set, and crossing the exterior edge exactly when it is, by the
parity at the left outer face. So the cut space of the graph and the cycle space of the dual
coincide, and comparing their dimensions is Euler's formula.
With S deleted, every vertex reached from the bottom of R sits an integer distance above
it.
Lean code for Lemma7.40●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CutSet.leancomplete
theorem IntegerRectangle.CutSet.int_sub_y₀_of_reflTransGen {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {S : Set (Option ι)} (hS : ∀ (i : ι), some i ∉ S → (T i).IsVTile) (hnone : none ∈ S) {s : IntegerRectangle.CutSet.Seg T} (h : Relation.ReflTransGen ((IntegerRectangle.CutSet.seymourMap hT).graph.deleteEdges S).Adj (IntegerRectangle.CutSet.vert hT (none, false)) s) : ∃ m, s.y - R.y₀ = ↑m
theorem IntegerRectangle.CutSet.int_sub_y₀_of_reflTransGen {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) {S : Set (Option ι)} (hS : ∀ (i : ι), some i ∉ S → (T i).IsVTile) (hnone : none ∈ S) {s : IntegerRectangle.CutSet.Seg T} (h : Relation.ReflTransGen ((IntegerRectangle.CutSet.seymourMap hT).graph.deleteEdges S).Adj (IntegerRectangle.CutSet.vert hT (none, false)) s) : ∃ m, s.y - R.y₀ = ↑m
**First alternative: a path of V-tiles.** A vertex reached from the bottom of `R` in Seymour's graph with the edges of `S` deleted, `S` containing the exterior edge and every tile that is not a V-tile, sits an integer distance above the bottom of `R`: each step crosses a V-tile.
Each step of the path crosses a V-tile, up or down, changing the height by an integer.
If deleting S cuts the bottom of R off from its top, the width of R is an integer.
Lean code for Lemma7.41●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/CutSet.leancomplete
theorem IntegerRectangle.CutSet.intWidth_of_not_reflTransGen {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) {S : Set (Option ι)} (hS : ∀ (i : ι), some i ∈ S → ¬(T i).IsVTile) (h : ¬Relation.ReflTransGen ((IntegerRectangle.CutSet.seymourMap hT).graph.deleteEdges S).Adj (IntegerRectangle.CutSet.vert hT (none, false)) (IntegerRectangle.CutSet.vert hT (none, true))) : R.IsHTile
theorem IntegerRectangle.CutSet.intWidth_of_not_reflTransGen {ι : Type} {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} [Fintype ι] (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) {S : Set (Option ι)} (hS : ∀ (i : ι), some i ∈ S → ¬(T i).IsVTile) (h : ¬Relation.ReflTransGen ((IntegerRectangle.CutSet.seymourMap hT).graph.deleteEdges S).Adj (IntegerRectangle.CutSet.vert hT (none, false)) (IntegerRectangle.CutSet.vert hT (none, true))) : R.IsHTile
**Second alternative: a dual path of H-tiles.** When the bottom of `R` is cut off from its top in Seymour's graph with the edges of `S` deleted, `S` containing only the exterior edge and tiles that are not V-tiles, a minimal `S' ⊆ S` cutting them off is a bond, which by planar duality is a cycle of the dual graph. The cycle passes through the exterior edge, since that edge alone joins the bottom to the top, and the rest of it is a path from the left outer face to the right one across H-tiles, each step moving the abscissa by the integer width of the tile crossed.
A minimal S' \subseteq S cutting the bottom off from the top is a bond of \Gamma, so by
planarity Lemma 7.39 and planar duality Theorem 7.36
its edges form a cycle of \Gamma^*, whose vertices are the V-links and the outer faces
Lemma 7.38. The cycle passes through the dual of the exterior edge, which
moves the abscissa from one side of R to the other. Every other step crosses an H-tile and
moves the abscissa by its integer width, and round the cycle the abscissa comes back, so the
width of R is an integer.
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_CutSet[complete]
-
IntegerRectangleTheorem_CutSet[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/CutSet.leancomplete
theorem IntegerRectangleTheorem_CutSet : IntegerRectangleTheorem
theorem IntegerRectangleTheorem_CutSet : IntegerRectangleTheorem
**Minimal cut-set proof** (Seymour) of the integer-rectangle tiling theorem. In Seymour's graph, delete the exterior edge and the tiles that are not V-tiles: either the top of `R` stays reachable from the bottom, across V-tiles, and the height of `R` is an integer; or a minimal set of deleted edges cutting it off is a bond, whose dual is a cycle through the exterior edge, and the rest of that cycle crosses `R` from left to right over H-tiles.
Form Seymour's graph Lemma 7.37 and delete S. If the top of R is
still reachable from the bottom, the height of R is an integer Lemma 7.40;
otherwise the width is Lemma 7.41.
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 of the ninth and tenth proofs.
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.43●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.widthSum T fun i ↦ (T i).y₀ = c ∧ c < (T i).y₁) = IntegerRectangle.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.widthSum T fun i ↦ (T i).y₀ = c ∧ c < (T i).y₁) = IntegerRectangle.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.25 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.44●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.widthSum T fun i ↦ (T i).y₀ = c ∧ c < (T i).y₁ ∧ ¬IntegerRectangle.SweepLine.IntHeight R (T i).y₁) - IntegerRectangle.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.widthSum T fun i ↦ (T i).y₀ = c ∧ c < (T i).y₁ ∧ ¬IntegerRectangle.SweepLine.IntHeight R (T i).y₁) - IntegerRectangle.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.43 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.45●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.25 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.44. 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–Máté). Take the bottom and left edges of R for the
axes, which replaces the standard position, and let \Gamma be the graph whose vertices are the
points of the x-axis at which some tile has a vertical edge and the points of the y-axis at which
some tile has a horizontal edge; two vertices on the x-axis are joined when an H-tile spans the
interval between them, and two on the y-axis when a V-tile does. Number the connected components
of \Gamma by distinct numbers in an arbitrary way, and let f be the step function whose value
on the interval between consecutive vertices x_i < x_{i+1} of the x-axis is the number of the
component of x_{i+1} less that of x_i, and g its counterpart on the y-axis. The
formalization builds \Gamma as a mathlib simple graph, and reads the value of f(x) g(y) on a
grid rectangle at its centre.
The values of f on the intervals between the two ends of the width of an H-tile add up to
0, and so do the values of g on the intervals between the two ends of the height of a V-tile.
Lean code for Lemma7.46●2 theorems
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/StepFunction.leancomplete
theorem IntegerRectangle.StepFunction.sum_stepX_eq_zero {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {i : ι} (h : (T i).IsHTile) : ∑ j ∈ Finset.Ico (IntegerRectangle.Grid.idxL R T i) (IntegerRectangle.Grid.idxR R T i), IntegerRectangle.StepFunction.stepX R T (IntegerRectangle.StepFunction.mid (IntegerRectangle.Grid.gridX R T) j) = 0
theorem IntegerRectangle.StepFunction.sum_stepX_eq_zero {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {i : ι} (h : (T i).IsHTile) : ∑ j ∈ Finset.Ico (IntegerRectangle.Grid.idxL R T i) (IntegerRectangle.Grid.idxR R T i), IntegerRectangle.StepFunction.stepX R T (IntegerRectangle.StepFunction.mid (IntegerRectangle.Grid.gridX R T) j) = 0
**The values of `f` on the intervals spanned by an H-tile add up to `0`.** The sum telescopes to the number of the component of the right end of the tile less that of its left end, and the two ends are joined by an edge of `Γ`.
-
theoremdefined in DifferentProofs/IntegerRectangle/StepFunction.leancomplete
theorem IntegerRectangle.StepFunction.sum_stepY_eq_zero {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {i : ι} (h : (T i).IsVTile) : ∑ k ∈ Finset.Ico (IntegerRectangle.Grid.idxB R T i) (IntegerRectangle.Grid.idxT R T i), IntegerRectangle.StepFunction.stepY R T (IntegerRectangle.StepFunction.mid (IntegerRectangle.Grid.gridY R T) k) = 0
theorem IntegerRectangle.StepFunction.sum_stepY_eq_zero {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {i : ι} (h : (T i).IsVTile) : ∑ k ∈ Finset.Ico (IntegerRectangle.Grid.idxB R T i) (IntegerRectangle.Grid.idxT R T i), IntegerRectangle.StepFunction.stepY R T (IntegerRectangle.StepFunction.mid (IntegerRectangle.Grid.gridY R T) k) = 0
**The values of `g` on the intervals spanned by a V-tile add up to `0`.**
The sum telescopes to the number of the component of one end less that of the other, and the two
ends are joined by an edge of \Gamma.
Extend the edges of the tiles of a tiling across R to a grid. Every open grid cell lies in exactly
one tile, and the cells in a tile form the product of two intervals of grid indices.
Lean code for Lemma7.47●1 theorem
Associated Lean declarations
-
IntegerRectangle.Grid.cellTile_eq_iff[complete]
-
IntegerRectangle.Grid.cellTile_eq_iff[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/Tiling/Grid.leancomplete
theorem IntegerRectangle.Grid.cellTile_eq_iff {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {p : ℕ × ℕ} {i : ι} (h₁ : p.1 + 1 < ((IntegerRectangle.Grid.gridX R T).sort fun a b ↦ a ≤ b).length) (h₂ : p.2 + 1 < ((IntegerRectangle.Grid.gridY R T).sort fun a b ↦ a ≤ b).length) : IntegerRectangle.Grid.cellTile hT p = i ↔ (IntegerRectangle.Grid.idxL R T i ≤ p.1 ∧ p.1 < IntegerRectangle.Grid.idxR R T i) ∧ IntegerRectangle.Grid.idxB R T i ≤ p.2 ∧ p.2 < IntegerRectangle.Grid.idxT R T i
theorem IntegerRectangle.Grid.cellTile_eq_iff {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) {p : ℕ × ℕ} {i : ι} (h₁ : p.1 + 1 < ((IntegerRectangle.Grid.gridX R T).sort fun a b ↦ a ≤ b).length) (h₂ : p.2 + 1 < ((IntegerRectangle.Grid.gridY R T).sort fun a b ↦ a ≤ b).length) : IntegerRectangle.Grid.cellTile hT p = i ↔ (IntegerRectangle.Grid.idxL R T i ≤ p.1 ∧ p.1 < IntegerRectangle.Grid.idxR R T i) ∧ IntegerRectangle.Grid.idxB R T i ≤ p.2 ∧ p.2 < IntegerRectangle.Grid.idxT R T i
**The fiber of `cellTile` over a tile is the product of its two index intervals.**
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.
Refine a tiling into its grid. A sum over the grid rectangles is the sum, over the tiles, of the sums over the grid rectangles in each tile.
Lean code for Lemma7.48●1 theorem
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/StepFunction.leancomplete
theorem IntegerRectangle.StepFunction.sum_grid_eq_sum_tiles {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (v : ℕ × ℕ → ℝ) : ∑ p ∈ Finset.range (((IntegerRectangle.Grid.gridX R T).sort fun a b ↦ a ≤ b).length - 1) ×ˢ Finset.range (((IntegerRectangle.Grid.gridY R T).sort fun a b ↦ a ≤ b).length - 1), v p = ∑ i, ∑ p ∈ Finset.Ico (IntegerRectangle.Grid.idxL R T i) (IntegerRectangle.Grid.idxR R T i) ×ˢ Finset.Ico (IntegerRectangle.Grid.idxB R T i) (IntegerRectangle.Grid.idxT R T i), v p
theorem IntegerRectangle.StepFunction.sum_grid_eq_sum_tiles {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (v : ℕ × ℕ → ℝ) : ∑ p ∈ Finset.range (((IntegerRectangle.Grid.gridX R T).sort fun a b ↦ a ≤ b).length - 1) ×ˢ Finset.range (((IntegerRectangle.Grid.gridY R T).sort fun a b ↦ a ≤ b).length - 1), v p = ∑ i, ∑ p ∈ Finset.Ico (IntegerRectangle.Grid.idxL R T i) (IntegerRectangle.Grid.idxR R T i) ×ˢ Finset.Ico (IntegerRectangle.Grid.idxB R T i) (IntegerRectangle.Grid.idxT R T i), v p
**The grid refinement.** Every grid rectangle lies in exactly one tile, and the grid rectangles in a tile form the product of its two index intervals (`Grid.filter_cellTile_eq`), so a sum over the grid rectangles is the sum, over the tiles, of the sums over the grid rectangles in each.
Every grid rectangle lies in exactly one tile, and those in a tile form the product of two intervals of grid indices Lemma 7.47.
The function f(x) g(y) is constant on each grid rectangle, and its values on the grid
rectangles in one tile add up to 0.
Lean code for Lemma7.49●2 theorems
Associated Lean declarations
-
theoremdefined in DifferentProofs/IntegerRectangle/StepFunction.leancomplete
theorem IntegerRectangle.StepFunction.step_of_mem_Ioo {s : Finset ℝ} (F : ℝ → ℝ) {j : ℕ} (hj : j + 1 < (s.sort fun a b ↦ a ≤ b).length) {x : ℝ} (hx : x ∈ Set.Ioo (IntegerRectangle.Grid.nth s j) (IntegerRectangle.Grid.nth s (j + 1))) : IntegerRectangle.StepFunction.step s F x = F (IntegerRectangle.Grid.nth s (j + 1)) - F (IntegerRectangle.Grid.nth s j)
theorem IntegerRectangle.StepFunction.step_of_mem_Ioo {s : Finset ℝ} (F : ℝ → ℝ) {j : ℕ} (hj : j + 1 < (s.sort fun a b ↦ a ≤ b).length) {x : ℝ} (hx : x ∈ Set.Ioo (IntegerRectangle.Grid.nth s j) (IntegerRectangle.Grid.nth s (j + 1))) : IntegerRectangle.StepFunction.step s F x = F (IntegerRectangle.Grid.nth s (j + 1)) - F (IntegerRectangle.Grid.nth s j)
The step function is constant on each gap of `s`.
-
theoremdefined in DifferentProofs/IntegerRectangle/StepFunction.leancomplete
theorem IntegerRectangle.StepFunction.sum_tile_eq_zero {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) (i : ι) : ∑ p ∈ Finset.Ico (IntegerRectangle.Grid.idxL R T i) (IntegerRectangle.Grid.idxR R T i) ×ˢ Finset.Ico (IntegerRectangle.Grid.idxB R T i) (IntegerRectangle.Grid.idxT R T i), IntegerRectangle.StepFunction.stepX R T (IntegerRectangle.StepFunction.mid (IntegerRectangle.Grid.gridX R T) p.1) * IntegerRectangle.StepFunction.stepY R T (IntegerRectangle.StepFunction.mid (IntegerRectangle.Grid.gridY R T) p.2) = 0
theorem IntegerRectangle.StepFunction.sum_tile_eq_zero {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) (i : ι) : ∑ p ∈ Finset.Ico (IntegerRectangle.Grid.idxL R T i) (IntegerRectangle.Grid.idxR R T i) ×ˢ Finset.Ico (IntegerRectangle.Grid.idxB R T i) (IntegerRectangle.Grid.idxT R T i), IntegerRectangle.StepFunction.stepX R T (IntegerRectangle.StepFunction.mid (IntegerRectangle.Grid.gridX R T) p.1) * IntegerRectangle.StepFunction.stepY R T (IntegerRectangle.StepFunction.mid (IntegerRectangle.Grid.gridY R T) p.2) = 0
**Over the grid rectangles in a tile, the values of `f(x) g(y)` add up to `0`**, being the product of the sums of the values of `f` along the width of the tile and of `g` along its height, one of which vanishes.
By construction f is constant on each interval between consecutive vertices of the x-axis, and
g on each interval of the y-axis. The grid rectangles in a tile form the product of two
intervals of grid indices Lemma 7.47, so the sum of the values of f(x) g(y)
over them is the product of the sums of the values of f along the width of the tile and of
g along its height, and one of these vanishes Lemma 7.46, the tile being
an H-tile or a V-tile.
The lower-left corner of R lies in the same component of \Gamma as its lower-right corner or
as its upper-left corner.
Lean code for Lemma7.50●1 theorem
Associated Lean declarations
-
IntegerRectangle.StepFunction.reachable[complete]
-
IntegerRectangle.StepFunction.reachable[complete]
-
theoremdefined in DifferentProofs/IntegerRectangle/StepFunction.leancomplete
theorem IntegerRectangle.StepFunction.reachable {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : (IntegerRectangle.StepFunction.graph R T).Reachable (IntegerRectangle.StepFunction.bot ⋯) (IntegerRectangle.StepFunction.bot ⋯) ∨ (IntegerRectangle.StepFunction.graph R T).Reachable (IntegerRectangle.StepFunction.left ⋯) (IntegerRectangle.StepFunction.left ⋯)
theorem IntegerRectangle.StepFunction.reachable {ι : Type} [Fintype ι] {R : IntegerRectangle.Rectangle} {T : ι → IntegerRectangle.Rectangle} (hT : IntegerRectangle.IsTiling R T) (hsides : ∀ (i : ι), (T i).HasIntegerSide) : (IntegerRectangle.StepFunction.graph R T).Reachable (IntegerRectangle.StepFunction.bot ⋯) (IntegerRectangle.StepFunction.bot ⋯) ∨ (IntegerRectangle.StepFunction.graph R T).Reachable (IntegerRectangle.StepFunction.left ⋯) (IntegerRectangle.StepFunction.left ⋯)
**The corner of `R` lies in the same component of `Γ` as one of its two neighbours.** Over the whole grid the values of `f(x) g(y)` add up to `0`, tile by tile, and their sum is the product of the sum of the values of `f` along the bottom edge of `R`, the number of the component of its lower-right corner less that of its lower-left one, with the corresponding sum of `g`.
By the grid refinement Lemma 7.48 the sum of the values of f(x) g(y) over
all the grid rectangles is the sum of its sums over the tiles, each of which is 0
Lemma 7.49. But it is the product of the sum of the values of f over all
the intervals of the x-axis, which telescopes to the number of the component of the lower-right
corner of R less that of its lower-left corner, with the corresponding sum of g. So one of
these vanishes, and the numbers of distinct components being distinct, the corner of R is in
the same component as one of the other two.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.51●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–Máté) of the integer-rectangle tiling theorem. The corner of `R` lies in the same component of Hochster and Máté's graph as the corner at the other end of its bottom edge or of its left edge (`reachable`), and a walk in the graph moves by a vector with integer entries.
Every edge of \Gamma spans a side of a tile of integer length, so two vertices in the same
component are an integer apart, and by Lemma 7.50 the width or the height
of R is an integer.
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.52●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.53●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.54●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.53. 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.55●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.56●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.54; 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.47, 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.57●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.52, 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.56. 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.54. The total is therefore odd.
A rectangle tiled by rectangles each with an integer side has an integer side.
Lean code for Theorem7.58●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.57, and in particular there is one. But every tile has an integer
side, so neither of its triangles is complete Lemma 7.55 — a
contradiction.