Monocurl Essays
Series Download

Proof by contradiction: why √2 is not a fraction

No fraction squares to exactly 2. To prove it, assume one does and follow the assumption until it breaks. That method is proof by contradiction.

23 min·High school and early college·

AssumesIf-then statements: converse and contrapositiveQuantifiers: for all, there exists, and negation

A square floor of side 17 holds 289 cells. Two square tiles of side 12 hold 288 between them. In opposite corners they overlap in 49 cells and leave two corners of 25 cells bare, so the tiles fall one cell short.
Monocurl source
let U = 3.7 / PP
let O = [-3.4, -1.85, 0]
let over = 2 * QQ - PP
let bare = PP - QQ
mesh tiles = Tiles(O, U, 0, PP, a: 0, b: 0)
mesh corners = []
mesh grid = [
    map(range(0, PP + 1), |i| Seg(cpt(O, U, i, 0), cpt(O, U, i, PP), MIST, 1)),
    map(range(0, PP + 1), |j| Seg(cpt(O, U, 0, j), cpt(O, U, PP, j), MIST, 1)),
    Outline([cpt(O, U, 0, 0), cpt(O, U, PP, 0), cpt(O, U, PP, PP), cpt(O, U, 0, PP)], INK, 3.5)
]
mesh words = [
    center{[2.2, 1.45, 0]} Note("floor", 0.76),
    center{[2.2, 0.95, 0]} Math(str_join([to_string(PP), "^2 = ", to_string(PP * PP)]), 0.95, INK)
]
mesh marks = []

slide "fit"
    play Wait(0.6)
    tiles.a = QQ
    play Lerp(1.5, [&tiles])
    tiles.b = QQ
    play Lerp(1.5, [&tiles])
    words .= center{[2.2, 0.1, 0]} Note("two tiles", 0.76)
    words .= center{[2.2, -0.4, 0]} Math(str_join(["2 \times ", to_string(QQ), "^2 = ", to_string(2 * QQ * QQ)]), 0.95, INK)
    play Fade(0.5, [&words])
    corners = [
        Cells(O, U, 0, QQ, bare, PP, GOLD, 0.4),
        Cells(O, U, QQ, 0, PP, bare, GOLD, 0.4)
    ]
    marks = [
        center{cpt(O, U, PP / 2, PP / 2)} Math(to_string(over * over), 1.0, INK),
        center{cpt(O, U, bare / 2, PP - bare / 2)} Math(to_string(bare * bare), 0.95, INK),
        center{cpt(O, U, PP - bare / 2, bare / 2)} Math(to_string(bare * bare), 0.95, INK),
        center{[2.2, -1.35, 0]} Cap(str_join([to_string(PP * PP - 2 * QQ * QQ), " cell short"]), 0.85, ROSE)
    ]
    play Fade(0.6, [&corners, &marks])
    play Wait(2.4)

Uses the shared definitions for this lesson's figures.

A square floor 17 units on a side has area 289. Two square tiles 12 units on a side have a combined area of 288. If the two numbers agreed we would have $17^2 = 2 \times 12^2$, which says $\left(\frac{17}{12}\right)^2 = 2$, and the fraction $\frac{17}{12}$ would be the square root of 2. It misses by one part in 289, and with all the whole numbers there are to choose from it seems certain that some other pair closes the gap.

No pair does, and this has been known for well over two thousand years. The puzzle is how anyone could know it, since there are infinitely many fractions and checking them one at a time never ends. A proof has to deal with every fraction at once. The method that does so is to suppose that a fraction with square 2 exists and to reason from that supposition until it produces something impossible.

Three earlier facts are used below. From truth tables: a statement is either true or false, and $Q \land \lnot Q$ is false whatever $Q$ is. From implication: $P \to Q$ is false only when $P$ is true and $Q$ is false, and it is equivalent to its contrapositive $\lnot Q \to \lnot P$. From quantifiers: the negation of “for all $x$, $A(x)$” is “there exists $x$ such that not $A(x)$”.

An integer is one of $\dots, -2, -1, 0, 1, 2, \dots$. An integer $n$ is even if $n = 2k$ for some integer $k$ and odd if $n = 2k + 1$ for some integer $k$; every integer is one or the other and none is both, because dividing by 2 leaves remainder 0 or 1. A rational number is a number that can be written $\frac{p}{q}$ with $p$ and $q$ integers and $q \neq 0$. A real number that is not rational is irrational.

What a search can and cannot show

By the Pythagorean theorem, the diagonal $d$ of a square of side 1 satisfies $d^2 = 1^2 + 1^2 = 2$. We write $\sqrt{2}$ for this length, about $1.41421$. A fraction $\frac{p}{q}$ of positive integers equals $\sqrt 2$ exactly when $\frac{p^2}{q^2} = 2$, that is, when

$$ p^2 = 2q^2. $$

So the question is whether a perfect square is ever exactly twice another. Try the small denominators: for each $q$, take the $p$ that brings $p^2$ nearest to $2q^2$.

For each denominator $q$ from 1 to 7, the numerator $p$ whose square comes nearest to $2q^2$. The last column is the miss $p^2 - 2q^2$, which is never zero.
Monocurl source
let QS = [1, 2, 3, 4, 5, 6, 7]
let best = |q| to_int(round(q * sqrt(2)))
let XS = [-3.1, -2.2, -0.95, 0.45, 1.75, 3.05]
let ry = |r| 1.15 - r * 0.47
let Row = |r| {
    let q = QS[r]
    let p = best(q)
    let miss = p * p - 2 * q * q
    return [
        center{[XS[0], ry(r), 0]} Math(to_string(q), 0.82, AZURE),
        center{[XS[1], ry(r), 0]} Math(to_string(p), 0.82, EMBER),
        center{[XS[2], ry(r), 0]} Math(to_string(p / q, 4), 0.82, SLATE),
        center{[XS[3], ry(r), 0]} Math(to_string(p * p), 0.82, EMBER),
        center{[XS[4], ry(r), 0]} Math(to_string(2 * q * q), 0.82, AZURE),
        center{[XS[5], ry(r), 0]} Math(to_string(miss), 0.82, ROSE)
    ]
}
mesh head = [
    center{[XS[0], 1.75, 0]} Math("q", 0.85, AZURE),
    center{[XS[1], 1.75, 0]} Math("p", 0.85, EMBER),
    center{[XS[2], 1.75, 0]} Math("p / q", 0.85, SLATE),
    center{[XS[3], 1.75, 0]} Math("p^2", 0.85, EMBER),
    center{[XS[4], 1.75, 0]} Math("2q^2", 0.85, AZURE),
    center{[XS[5], 1.75, 0]} Math("p^2 - 2q^2", 0.8, ROSE),
    Seg([-3.5, 1.45, 0], [3.7, 1.45, 0], SLATE, 2)
]
mesh rows = [Row(0)]

slide "search"
    play Wait(0.7)
    for (k in range(2, len(QS) + 1)) {
        rows = map(range(0, k), |r| Row(r))
        play Fade(0.4, [&rows])
        play Wait(0.45)
    }
    play Wait(2.2)

Uses the shared definitions for this lesson's figures.

All seven denominators miss. Larger numbers come closer in proportion, as $99^2 = 9801$ against $2 \times 70^2 = 9800$ does, but a table of any length leaves infinitely many denominators unexamined. If the answer is “never”, we need a reason that applies to all of them, and the table contains a hint of one.

Pause and try

Every entry in the column $2q^2$ is even. If the two columns $p^2$ and $2q^2$ are ever to agree, what must be true of $p^2$? Now look at the rows where $p$ is odd. Could any row with an odd $p$ have been exact?

Show answerHide answer

For the columns to agree, $p^2$ must be even. The rows with odd $p$ are $p = 1, 3, 7$, with squares $1, 9, 49$, all odd. An odd number cannot equal an even one, so those rows had no chance. This suggests that the square of an odd number is always odd, which would mean that only an even $p$ can work.

Odd numbers have odd squares

Dots show why. Arrange $7 \times 7$ dots in a square and pair them off.

Pairing the dots of a 7 by 7 square. Each row gives three pairs and one spare dot, and the seven spare dots give three more pairs, with one dot left over at the end: $49 = 2 \times 24 + 1$.
Monocurl source
let N = 7
let H = (N - 1) // 2
let S = 0.48
let spot = |i, j| [-1.8 + (i - H) * S, (H - j) * S, 0]
let PAIRS = block {
    for (j in range(0, N)) {
        for (i in range(0, H)) {
            . [[2 * i, j], [2 * i + 1, j]]
        }
    }
    for (j in range(0, H)) {
        . [[N - 1, 2 * j], [N - 1, 2 * j + 1]]
    }
}
let Links = |k| block {
    for (m in range(0, len(PAIRS))) {
        if (k > m + 0.5) {
            let a = spot(PAIRS[m][0][0], PAIRS[m][0][1])
            let b = spot(PAIRS[m][1][0], PAIRS[m][1][1])
            . Seg(a, b, AZURE, 9)
            . Pt(a, AZURE, 0.13)
            . Pt(b, AZURE, 0.13)
        }
    }
    . center{[2.2, 0.7, 0]} scale{1.5} color{AZURE} Number(floor(k + 0.5), 0)
}
mesh dots = [
    map(range(0, N), |i| map(range(0, N), |j| Pt(spot(i, j), SLATE, 0.13))),
    center{[2.2, 1.35, 0]} Note("pairs made", 0.78)
]
mesh links = Links(k: 0)
mesh last = []

slide "pair"
    play Wait(0.6)
    links.k = len(PAIRS)
    play Lerp(5, [&links], linear)
    last = [
        Pt(spot(N - 1, N - 1), ROSE, 0.15),
        center{[2.2, -0.35, 0]} Math(str_join([to_string(N), "^2 = 2 \times ", to_string(len(PAIRS)), " + 1"]), 0.9, INK),
        center{[2.2, -1.1, 0]} Cap("one dot left over", 0.82, ROSE)
    ]
    play Fade(0.5, [&last])
    play Wait(2)

Uses the shared definitions for this lesson's figures.

The same pairing works for any odd side length. We want the statement “if $n^2$ is even then $n$ is even”, and the dots argue from the other end: they start with $n$ odd and conclude that $n^2$ is odd. That is the contrapositive, which is an equivalent statement, so proving it is enough.

The parity proof

Apply the lemma to a supposed solution of $p^2 = 2q^2$. The right side is even, so $p^2$ is even, so $p$ is even, say $p = 2k$. Then $4k^2 = 2q^2$, so $q^2 = 2k^2$, and by the lemma again $q$ is even. Any fraction equal to $\sqrt 2$ would have an even numerator and an even denominator.

That is strange but not yet impossible, since $\frac{6}{4}$ has the same feature. The trouble is that it must hold for every fraction equal to $\sqrt 2$, including the one left after cancelling the 2. To get a clean impossibility we begin with a fraction from which nothing can be cancelled. A fraction $\frac{p}{q}$ with $q > 0$ is in lowest terms if no integer greater than 1 divides both $p$ and $q$. Every rational number can be written in lowest terms: among all the ways of writing it with a positive denominator, take one whose denominator is as small as possible. If some $d > 1$ divided both $p$ and $q$, then $\frac{p/d}{q/d}$ would be the same number with a smaller denominator.

  1. Suppose the square root of 2 is a fraction p/q in lowest terms.
  2. Clearing the denominator gives p² = 2q². Then p² is even, so by the lemma p is even.
  3. Write p = 2k. Then 4k² = 2q², so q² = 2k², and by the lemma q is even too.
  4. Both p and q are even, so they share the factor 2, which contradicts the first line.
The parity proof as a chain. Each line follows from the ones above it, and the last line clashes with the first.
Monocurl source
let LINES = [
    ["\sqrt{2} = \frac{p}{q} \text{ in lowest terms}", "suppose"],
    ["p^2 = 2q^2", "multiply by q squared"],
    ["p \text{ is even: } p = 2k", "parity lemma"],
    ["q^2 = 2k^2", "substitute, halve"],
    ["q \text{ is even}", "parity lemma"]
]
let ly = |i| 1.72 - i * 0.64
let Line1 = |i, on| [
    center{[-1.5, ly(i), 0]} Math(LINES[i][0], 0.88, [MIST, INK][on]),
    center{[2.25, ly(i), 0]} Cap(LINES[i][1], 0.76, [MIST, SLATE][on])
]
let Upto = |n| map(range(0, 5), |i| Line1(i, to_int(i < n)))
mesh lines = Upto(0)
mesh clash = []

slide "Suppose the square root of 2 is a fraction p/q in lowest terms."
    lines = Upto(1)
    play Fade(0.6)

slide "Clearing the denominator gives p² = 2q². Then p² is even, so by the lemma p is even."
    lines = Upto(3)
    play Fade(0.6)

slide "Write p = 2k. Then 4k² = 2q², so q² = 2k², and by the lemma q is even too."
    lines = Upto(5)
    play Fade(0.6)

slide "Both p and q are even, so they share the factor 2, which contradicts the first line."
    clash = [
        FrameBox(-3.5, 0.5, ly(0) - 0.4, ly(0) + 0.4, ROSE, 4),
        center{[-1.5, ly(5) - 0.05, 0]} Cap("2 divides both p and q", 0.85, ROSE),
        FrameBox(-3.5, 0.5, ly(5) - 0.38, ly(5) + 0.28, ROSE, 4),
        Path([[0.5, ly(0), 0], [0.95, ly(0), 0], [0.95, ly(5) - 0.05, 0], [0.5, ly(5) - 0.05, 0]], ROSE, 4),
        center{[2.25, ly(5) - 0.05, 0]} Cap("cannot both hold", 0.8, ROSE)
    ]
    play Fade(0.6)

Uses the shared definitions for this lesson's figures.

Pause and try

Run the same five steps on the false claim “no rational number has square 4”, starting from $p^2 = 4q^2$. At which step does the argument stop producing what it needs?

Show answerHide answer

Step 2 survives: $p^2 = 4q^2$ is even, so $p = 2k$. Step 3 becomes $4k^2 = 4q^2$, that is, $k^2 = q^2$, and this says nothing about whether $q$ is even. Step 4 has no support, and no contradiction appears, which is as it should be because $\frac{2}{1}$ has square 4. The proof for 2 used the fact that halving $4k^2 = 2q^2$ leaves a factor of 2 on one side only.

The shape of the argument

Set the arithmetic aside and look at the logic. We wanted to establish a statement $P$: “no rational number has square 2”. We assumed $\lnot P$. From that assumption we derived a statement $Q$ (“no integer greater than 1 divides both $p$ and $q$”) together with $\lnot Q$. So we showed that the conditional

$$ \lnot P \to (Q \land \lnot Q) $$

is true. The table shows why that settles $P$.

The truth table of \lnot P \to (Q \land \lnot Q). The contradiction Q \land \lnot Q is false in every row, so the conditional is true exactly in the rows where P is true.
The truth table of $\lnot P \to (Q \land \lnot Q)$. The contradiction $Q \land \lnot Q$ is false in every row, so the conditional is true exactly in the rows where $P$ is true.
Monocurl source
let R2 = [[1, 1], [1, 0], [0, 1], [0, 0]]
let XS = [-3.1, -2.15, -1.1, 0.25, 2.3]
let Y0 = 1.0
let DY = 0.72
let IMP = |a, b| max(1 - a, b)
let vp = map(R2, |r| r[0])
let vq = map(R2, |r| r[1])
let vnp = map(R2, |r| 1 - r[0])
let vc = map(R2, |r| r[1] * (1 - r[1]))
let vf = map(R2, |r| IMP(1 - r[0], r[1] * (1 - r[1])))
mesh head = [
    center{[XS[0], 1.75, 0]} Math("P", 0.9, AZURE),
    center{[XS[1], 1.75, 0]} Math("Q", 0.9, EMBER),
    center{[XS[2], 1.75, 0]} Math("\lnot P", 0.85, AZURE),
    center{[XS[3], 1.75, 0]} Math("Q \land \lnot Q", 0.85, ROSE),
    center{[XS[4], 1.75, 0]} Math("\lnot P \to (Q \land \lnot Q)", 0.8, PLUM)
]
mesh table = [
    Col(XS[0], Y0, DY, vp, AZURE, 0.74, 0.5),
    Col(XS[1], Y0, DY, vq, EMBER, 0.74, 0.5),
    Col(XS[2], Y0, DY, vnp, AZURE, 0.74, 0.5),
    Col(XS[3], Y0, DY, vc, ROSE, 0.74, 0.5),
    Col(XS[4], Y0, DY, vf, PLUM, 0.74, 0.5)
]
mesh same = [
    FrameBox(XS[0] - 0.47, XS[0] + 0.47, Y0 - 3 * DY - 0.36, Y0 + 0.36, LEAF),
    FrameBox(XS[4] - 0.47, XS[4] + 0.47, Y0 - 3 * DY - 0.36, Y0 + 0.36, LEAF),
    center{[0, -1.9, 0]} Cap(["the framed columns differ", "the two framed columns are the same"][to_int(all(map(range(0, 4), |i| vp[i] == vf[i])))], 0.82, LEAF)
]

Uses the shared definitions for this lesson's figures.

A conditional with a false conclusion is true only when its hypothesis is false. So once we know this conditional is true, we know that $\lnot P$ is false, and since every statement is true or false, $P$ is true.

When $P$ is a conditional $A \to B$, its negation is $A \land \lnot B$, so a proof by contradiction of “if $A$ then $B$” starts by assuming $A$ and $\lnot B$. Compare this with the two other ways to prove a conditional.

MethodYou assumeYou must reach
Direct proof$A$$B$
Contrapositive$\lnot B$$\lnot A$
Contradiction$A$ and $\lnot B$any contradiction

The parity lemma was proved by contrapositive: we assumed $n$ is odd and aimed at “$n^2$ is odd”, never using the hypothesis “$n^2$ is even”. A proof by contradiction is looser on both sides. It gives you two assumptions to work with instead of one, and it does not say in advance what the contradiction will be: for $\sqrt 2$ it concerned lowest terms, which the theorem does not mention. If a contradiction argument reaches $\lnot A$ without ever using $A$, it was a contrapositive proof and is cleaner written as one.

The freedom has a cost. Everything written after “suppose” describes a situation that does not exist if the proof succeeds, so no line can be tested on an example, and an algebra slip produces an absurdity that looks the same as the one you were hoping for.

A second proof: the smaller square

The tiles from the opening give a second proof, with a different kind of contradiction.

Suppose $p^2 = 2q^2$ for positive integers $p$ and $q$. Then a square floor of side $p$ has exactly the area of two square tiles of side $q$. Since $q^2 < p^2 = 2q^2 < 4q^2$, we have $q < p < 2q$: one tile is smaller than the floor, and two side by side are too wide for it. Push the tiles into opposite corners.

  1. Suppose p² = 2q². Then a square floor of side p has the same area as two square tiles of side q.
  2. Put the tiles in opposite corners. They overlap in a square of side 2q − p and leave two bare corners of side p − q.
  3. The tiles have the area of the floor, so what is covered twice must equal what is not covered: (2q − p)² = 2(p − q)².
  4. For 17 and 12 the smaller pair is 7 and 5, and 49 against 50 misses by one again.
  5. The middle square is a floor of side 7 for two tiles of side 5. Inside it they overlap in a square of side 3 and leave corners of side 2.
The floor and the two tiles, drawn to scale for the near miss $p = 17$, $q = 12$. If the tiles had exactly the area of the floor, the square covered twice would have exactly the area of the two bare corners.
Monocurl source
let U = 0.215
let O = [-3.45, -1.8, 0]
let over = 2 * QQ - PP
let bare = PP - QQ
let Side = |tex, ypos, col = INK, size = 0.85| center{[2.3, ypos, 0]} Math(tex, size, col)
mesh grid = [
    map(range(1, PP), |i| Seg(cpt(O, U, i, 0), cpt(O, U, i, PP), MIST, 1)),
    map(range(1, PP), |j| Seg(cpt(O, U, 0, j), cpt(O, U, PP, j), MIST, 1))
]
mesh tiles = []
mesh corners = []
mesh inner = []
mesh floor = Outline([cpt(O, U, 0, 0), cpt(O, U, PP, 0), cpt(O, U, PP, PP), cpt(O, U, 0, PP)], INK, 3.5)
mesh labels = []
mesh words = []

slide "Suppose p² = 2q². Then a square floor of side p has the same area as two square tiles of side q."
    labels = [
        Plate(cpt(O, U, PP / 2, PP / 2), [1.5, 0.6]),
        center{cpt(O, U, PP / 2, PP / 2)} Math("p \times p", 1.0, INK)
    ]
    words = [
        Side("p^2 = 2q^2", 0.9, INK, 0.95),
        center{[2.3, 0.15, 0]} Note("drawn with", 0.76),
        Side(str_join(["p = ", to_string(PP), ",\; q = ", to_string(QQ)]), -0.35, SLATE)
    ]
    play Fade(0.6)

slide "Put the tiles in opposite corners. They overlap in a square of side 2q − p and leave two bare corners of side p − q."
    labels = []
    words = []
    play Fade(0.3, [&labels, &words])
    tiles = Tiles(O, U, 0, PP, QQ, QQ)
    corners = [
        Cells(O, U, 0, QQ, bare, PP, GOLD, 0.4),
        Cells(O, U, QQ, 0, PP, bare, GOLD, 0.4)
    ]
    labels = [
        center{cpt(O, U, bare / 2, bare / 2)} Math("q \times q", 0.85, AZURE),
        center{cpt(O, U, PP - bare / 2, PP - bare / 2)} Math("q \times q", 0.85, EMBER),
        center{cpt(O, U, PP / 2, PP / 2)} Math("2q - p", 0.88, INK),
        center{cpt(O, U, bare / 2, PP - bare / 2)} Math("p - q", 0.85, INK),
        center{cpt(O, U, PP - bare / 2, bare / 2)} Math("p - q", 0.85, INK)
    ]
    words = [
        center{[2.3, 0.9, 0]} Cap("covered twice", 0.82, PLUM),
        center{[2.3, 0.1, 0]} Cap("not covered", 0.82, GOLD)
    ]
    play Fade(0.6)

slide "The tiles have the area of the floor, so what is covered twice must equal what is not covered: (2q − p)² = 2(p − q)²."
    words = []
    play Fade(0.3, [&words])
    words = [
        Side("(2q - p)^2", 0.95, PLUM, 0.9),
        Side("=", 0.4, INK, 0.9),
        Side("2\,(p - q)^2", -0.15, GOLD, 0.9),
        center{[2.3, -1.0, 0]} Note("a smaller pair", 0.78)
    ]
    play Fade(0.5, [&words])

slide "For 17 and 12 the smaller pair is 7 and 5, and 49 against 50 misses by one again."
    labels = []
    words = []
    play Fade(0.3, [&labels, &words])
    labels = [
        center{cpt(O, U, PP / 2, PP / 2)} Math(str_join([to_string(over), "\times", to_string(over)]), 0.85, INK),
        center{cpt(O, U, bare / 2, PP - bare / 2)} Math(str_join([to_string(bare), "\times", to_string(bare)]), 0.8, INK),
        center{cpt(O, U, PP - bare / 2, bare / 2)} Math(str_join([to_string(bare), "\times", to_string(bare)]), 0.8, INK)
    ]
    words = [
        Side(str_join([to_string(over), "^2 = ", to_string(over * over)]), 0.9, PLUM, 0.95),
        Side(str_join(["2 \times ", to_string(bare), "^2 = ", to_string(2 * bare * bare)]), 0.2, GOLD, 0.95)
    ]
    play Fade(0.5, [&labels, &words])

slide "The middle square is a floor of side 7 for two tiles of side 5. Inside it they overlap in a square of side 3 and leave corners of side 2."
    labels = [
        center{cpt(O, U, bare / 2, PP - bare / 2)} Math(str_join([to_string(bare), "\times", to_string(bare)]), 0.8, INK),
        center{cpt(O, U, PP - bare / 2, bare / 2)} Math(str_join([to_string(bare), "\times", to_string(bare)]), 0.8, INK)
    ]
    words = []
    play Fade(0.3, [&labels, &words])
    inner = [
        Cells(O, U, bare, bare, QQ, QQ, GOLD, 0.4, 3),
        Tiles(O, U, bare, over, bare, bare),
        Outline([cpt(O, U, bare, bare), cpt(O, U, QQ, bare), cpt(O, U, QQ, QQ), cpt(O, U, bare, QQ)], INK, 3.5)
    ]
    words = [
        Side(str_join([to_string(PP), ",\ ", to_string(QQ)]), 1.1, INK, 0.95),
        Side(str_join(["\downarrow\ \ ", to_string(over), ",\ ", to_string(bare)]), 0.35, INK, 0.95),
        Side(str_join(["\downarrow\ \ ", to_string(down([over, bare])[0]), ",\ ", to_string(down([over, bare])[1])]), -0.4, INK, 0.95)
    ]
    play Fade(0.6, [&inner, &words])

Uses the shared definitions for this lesson's figures.

Here is the accounting behind the third step. The two tiles together cover the floor except for the two bare corners, and they cover the middle square twice. So

$$ 2q^2 = \bigl(p^2 - 2(p-q)^2\bigr) + (2q - p)^2. $$

If $p^2 = 2q^2$, the two leftover terms must cancel: $(2q - p)^2 = 2(p - q)^2$. Algebra confirms this without the picture:

$$ (2q - p)^2 - 2(p - q)^2 = 4q^2 - 4pq + p^2 - 2p^2 + 4pq - 2q^2 = 2q^2 - p^2, $$

which is 0 when $p^2 = 2q^2$.

So from one solution $(p, q)$ in positive integers we get another, $(2q - p,\; p - q)$. Both entries are positive integers because $q < p < 2q$, and the new second entry is smaller than the old one, since $p - q < q$. Apply the step again and again, and the second entries form a strictly decreasing sequence of positive integers that never ends. But there are only eleven positive integers below 12, so a decreasing sequence of positive integers that starts at 12 has at most twelve terms, and the same goes for any starting value.

The step $(p, q) \to (2q - p,\ p - q)$ applied to the near miss $(17, 12)$. The second entry hops from 12 to 5 to 2 to 1, where no smaller positive integer is left. An exact solution would have to keep hopping forever.
Monocurl source
let ux = |v| -3.3 + v * 0.55
let YL = -0.95
var chain = [[PP, QQ]]
for (i in range(0, 3)) {
    chain .= down(chain[i])
}
let CH = chain
let Hop = |a, b, f| {
    let c = (ux(a) + ux(b)) / 2
    let r = (ux(a) - ux(b)) / 2
    let h = 0.5 + 0.62 * r
    let n = to_int(max(2, ceil(30 * f)))
    return Path(map(sample(0, PI * f, n), |t| [c + r * cos(t), YL + h * sin(t), 0]), EMBER, 4)
}
let Hops = |k| block {
    for (i in range(0, len(CH) - 1)) {
        let f = clamp(0, k - i, 1)
        if (f > 0.03) {
            . Hop(CH[i][1], CH[i + 1][1], f)
        }
        if (k >= i + 1 - 0.001) {
            . Pt([ux(CH[i + 1][1]), YL, 0], EMBER, 0.13)
        }
    }
}
let PairTex = |i| center{[-2.85 + i * 1.9, 1.7, 0]} Math(str_join(["(", to_string(CH[i][0]), ",\,", to_string(CH[i][1]), ")"]), 1.0, INK)
mesh line = [
    Seg([ux(0), YL, 0], [ux(12.5), YL, 0], SLATE, 2.5),
    map(range(0, 13), |v| [
        Seg([ux(v), YL - 0.09, 0], [ux(v), YL + 0.09, 0], SLATE, 2),
        center{[ux(v), YL - 0.38, 0]} Math(to_string(v), 0.74, SLATE)
    ]),
    Pt([ux(QQ), YL, 0], EMBER, 0.13)
]
mesh hops = Hops(k: 0)
mesh pairs = [PairTex(0)]
mesh stop = []

slide "descend"
    play Wait(0.6)
    for (i in range(1, len(CH))) {
        hops.k = i
        play Lerp(1.2, [&hops])
        pairs .= center{[-2.85 + i * 1.9 - 0.95, 1.7, 0]} Math("\to", 0.85, SLATE)
        pairs .= PairTex(i)
        play Fade(0.35, [&pairs])
    }
    stop = [
        Tip([ux(1) - 0.06, YL + 0.3, 0], [ux(0) + 0.12, YL + 0.3, 0], ROSE, 3.5, 0.16),
        center{[ux(0) + 0.1, YL + 0.75, 0]} Cap("?", 1.0, ROSE),
        center{[-1.75, -1.85, 0]} Cap("no positive integer below 1", 0.82, ROSE)
    ]
    play Fade(0.5, [&stop])
    play Wait(2.2)

Uses the shared definitions for this lesson's figures.

This style of argument is called infinite descent: show that any solution yields a smaller one, and conclude that there is none. The fact about positive integers that it rests on has a name.

We take this as a basic property of the positive integers; it is logically equivalent to the principle of induction. It is special to them: the positive rationals have no least element (halve any candidate), and neither does the set of all integers. With the principle named, the descent becomes a short proof by contradiction.

The first proof leaned on the same principle without saying so. “Take a way of writing $r$ whose denominator is as small as possible” is a use of well-ordering.

Infinitely many primes

A prime is an integer greater than 1 whose only positive divisors are 1 and itself: $2, 3, 5, 7, 11, 13, \dots$ They thin out as numbers grow, and it is fair to ask whether they stop. One preliminary fact is needed, and well-ordering supplies it.

Pause and try

Let $N = 2 \times 3 \times 5 \times 7 + 1 = 211$. What remainder does $N$ leave on division by each of 2, 3, 5 and 7? What does that tell you about the prime that the lemma promises?

Show answerHide answer

$N$ is 1 more than a multiple of each of them, so each division leaves remainder 1, and none of 2, 3, 5, 7 divides $N$. The lemma says some prime divides $N$, so that prime is not one of 2, 3, 5, 7. (In this case 211 is itself prime.)

  1. For the lists 2, then 2 and 3, then 2, 3 and 5, the number N is 3, 7 and 31. Each is a prime that is not on its list.
  2. Two more lists give 211 and 2311, also prime. It is tempting to guess that N is always prime.
  3. With six primes, N = 30031 = 59 × 509. It is not prime, but its prime factors 59 and 509 are not on the list.
Euclid’s construction run on the lists of the first one to six primes. The number $N$ is the product of the list plus 1. It is prime for the first five lists and composite for the sixth.
Monocurl source
let PRIMES = [2, 3, 5, 7, 11, 13]
let spf = |n| {
    var d = 2
    while (d * d <= n and mod(n, d) != 0) {
        d = d + 1
    }
    if (d * d > n) {
        return n
    }
    return d
}
let ry = |r| 1.1 - r * 0.56
let Row = |r| {
    let lst = take(PRIMES, r + 1)
    let n = product(lst) + 1
    let d = spf(n)
    let isp = to_int(d == n)
    return [
        center{[0.85, ry(r), 0]} Math(to_string(n), 0.85, AZURE),
        center{[2.6, ry(r), 0]} Math(["", "\text{prime}"][isp], 0.82, LEAF),
        center{[2.6, ry(r), 0]} Math([str_join([to_string(d), " \times ", to_string(n // d)]), ""][isp], 0.85, EMBER)
    ]
}
mesh head = [
    center{[-1.75, 1.78, 0]} Note("product of the list, plus 1", 0.76),
    center{[0.85, 1.78, 0]} Math("N", 0.88, AZURE),
    center{[2.6, 1.78, 0]} Note("N factored", 0.76),
    Seg([-3.55, 1.47, 0], [3.55, 1.47, 0], SLATE, 2)
]
let Lists = map(range(0, 6), |r| center{[-1.75, ry(r), 0]} Math(str_join([str_join(map(take(PRIMES, r + 1), |p| to_string(p)), " \cdot "), " + 1"]), 0.8, INK))
let Pending = |k| map(range(k, 6), |r| center{[0.85, ry(r), 0]} Math("?", 0.85, MIST))
mesh lists = []
mesh pending = []
mesh rows = []
mesh mark = []

slide "For the lists 2, then 2 and 3, then 2, 3 and 5, the number N is 3, 7 and 31. Each is a prime that is not on its list."
    lists = Lists
    pending = Pending(3)
    rows = map(range(0, 3), |r| Row(r))
    play Fade(0.6)

slide "Two more lists give 211 and 2311, also prime. It is tempting to guess that N is always prime."
    pending = Pending(5)
    play Fade(0.3, [&pending])
    rows = map(range(0, 5), |r| Row(r))
    play Fade(0.6)

slide "With six primes, N = 30031 = 59 × 509. It is not prime, but its prime factors 59 and 509 are not on the list."
    pending = []
    play Fade(0.3, [&pending])
    rows = map(range(0, 6), |r| Row(r))
    mark = [FrameBox(-3.55, 3.55, ry(5) - 0.3, ry(5) + 0.3, EMBER, 3.5)]
    play Fade(0.6)

Uses the shared definitions for this lesson's figures.

Be careful about what $N$ is. The proof never says that $N$ is prime, and in general it is not: $2 \cdot 3 \cdot 5 \cdot 7 \cdot 11 \cdot 13 + 1 = 30031 = 59 \times 509$. Nor is $N$, or its smallest prime factor, the next prime after the list: for the list $2, 3$ we get $N = 7$, which skips 5. The only property used is that no prime on the list divides $N$, while some prime does.

Without its first and last sentences, the proof shows something positive: given any finite list of primes, there is a prime not on the list. That is how Euclid stated it, and it is a recipe too, since the smallest prime factor of $N$ can be computed.

Worked examples

A proof to debug

Pause and try

Find the error in the following argument, and decide whether the claim is true.

Claim. The sum of two irrational numbers is always irrational.

”Proof.” Suppose not. Then the sum of two irrational numbers is rational. Take the irrational numbers $\sqrt 2$ and $\sqrt 2$. Their sum is $2\sqrt 2$. If $2\sqrt 2$ were a rational number $s$, then $\sqrt 2 = \frac{s}{2}$ would be rational, which it is not. So $2\sqrt 2$ is irrational, contradicting the supposition. Hence the claim holds.

Show answerHide answer

The claim is “for all irrational $a$ and $b$, $a + b$ is irrational”. Its negation is “there exist irrational $a$ and $b$ with $a + b$ rational”. The “proof” instead supposed that every sum of two irrationals is rational, refuted that with one example, and concluded the original claim. It negated “for all” as “for none”. The claim itself is false: $\sqrt 2$ and $-\sqrt 2$ are irrational and their sum is 0.

Common mistakes and limits

The method and the result both have limits. A contradiction shows that something is so without always showing why, so when a direct proof is available it is usually the more informative one. The parity argument, for its part, does not settle every square root at once: for a positive integer $n$, $\sqrt n$ is rational only when $n$ is a perfect square, but we proved this only for $n = 2$ and $n = 3$. The general proof uses unique factorization into primes, which we have not established.

Stepping back

The difficulty at the start was the word “no”: a claim that among infinitely many fractions not one works. Contradiction converts such a claim into reasoning about a single imagined object. Assume a counterexample exists, give it a name, and you can compute with it until it is forced to have two incompatible properties. In both proofs the pressure came from size: lowest terms and the least element both say “there is nothing smaller”, and the supposed solution kept producing something smaller. The next lesson turns from proving to counting, and the lesson after it uses contradiction once more, on infinite sets.

Check yourself

You want to prove by contradiction: “for every integer $n$, if $n^2$ is divisible by 3 then $n$ is divisible by 3”. What do you assume?

Problems

Problems 1 to 3 repeat the moves of the lesson, 4 to 6 combine them, and 7 and 8 go further.

Problem 1

Prove that for every integer $n$, if $n^2$ is odd then $n$ is odd. State which method you used.

Show solutionHide solution

By contrapositive: we show that if $n$ is not odd then $n^2$ is not odd. If $n$ is not odd it is even, so $n = 2k$ for an integer $k$, and $n^2 = 4k^2 = 2(2k^2)$ is even, hence not odd.

Problem 2

Run Euclid’s construction on each list of primes and factor the result: (a) $3, 5, 7$; (b) $2, 7$. In each case check that no prime factor of $N$ is on the list, and say whether $N$ is prime.

Show solutionHide solution

(a) $N = 3 \cdot 5 \cdot 7 + 1 = 106 = 2 \times 53$. Not prime; its prime factors 2 and 53 are not among 3, 5, 7. (b) $N = 2 \cdot 7 + 1 = 15 = 3 \times 5$. Not prime; 3 and 5 are not among 2, 7. The new primes can be smaller than the ones on the list.

Problem 3

Let $x$ be irrational and let $r$ be a rational number with $r \neq 0$. Prove that $rx$ is irrational. Where is $r \neq 0$ used, and what happens without it?

Show solutionHide solution

Suppose, for contradiction, that $x$ is irrational, $r \neq 0$ is rational, and $rx$ is rational, say $rx = s$. Because $r \neq 0$ we may divide: $x = \frac{s}{r}$. A quotient of two rationals with nonzero divisor is rational, since $\frac{a}{b} \div \frac{c}{d} = \frac{ad}{bc}$ and $c \neq 0$ when $r = \frac{c}{d} \neq 0$. So $x$ is rational, a contradiction. The hypothesis $r \neq 0$ was used to divide. Without it the statement is false: $0 \cdot \sqrt 2 = 0$ is rational.

Problem 4

Prove that $\sqrt[3]{2}$ is irrational.

Show solutionHide solution

First a lemma: if $n^3$ is even then $n$ is even. By contrapositive, if $n = 2k + 1$ then $n^3 = 8k^3 + 12k^2 + 6k + 1 = 2(4k^3 + 6k^2 + 3k) + 1$ is odd. Now suppose, for contradiction, that $\sqrt[3]{2} = \frac{p}{q}$ in lowest terms with $p, q$ positive integers. Cubing, $p^3 = 2q^3$, so $p^3$ is even and $p = 2k$. Then $8k^3 = 2q^3$, so $q^3 = 4k^3 = 2(2k^3)$ is even, and $q$ is even. So 2 divides both $p$ and $q$, contradicting lowest terms.

Problem 5

Start from the near miss $(p, q) = (99, 70)$ and apply the step $(p, q) \to (2q - p,\ p - q)$ until the second entry reaches 1. Record $p^2 - 2q^2$ at each stage. Then explain the pattern using the identity from the lesson.

Show solutionHide solution

The pairs are $(99, 70) \to (41, 29) \to (17, 12) \to (7, 5) \to (3, 2) \to (1, 1)$; for instance $2 \cdot 70 - 99 = 41$ and $99 - 70 = 29$. The values of $p^2 - 2q^2$ are $9801 - 9800 = 1$, $1681 - 1682 = -1$, $289 - 288 = 1$, $49 - 50 = -1$, $9 - 8 = 1$, $1 - 2 = -1$. The identity $(2q - p)^2 - 2(p - q)^2 = 2q^2 - p^2 = -(p^2 - 2q^2)$ says each step flips the sign of the miss and keeps its size. So a miss of $\pm 1$ stays $\pm 1$ all the way down, and an exact solution, with miss 0, would stay exact all the way down, which is what the descent proof exploits.

Problem 6

Find the flaw. Claim: 1 is the largest positive integer. ”Proof”: Let $n$ be the largest positive integer. Suppose, for contradiction, that $n \neq 1$. Then $n \geq 2$, so $n^2 > n$. But $n^2$ is a positive integer, and it is larger than the largest positive integer, a contradiction. Hence $n = 1$.

Show solutionHide solution

The first sentence assumes that a largest positive integer exists. That was never proved, and it is false, since $n + 1 > n$ for every $n$. The steps after it are valid, and what they establish is the conditional “if a largest positive integer $n$ exists, then $n = 1$”. A conditional with a false hypothesis is true and tells us nothing about its conclusion. The contradiction came from two assumptions together, “$n$ is the largest positive integer” and “$n \neq 1$”, and the argument blamed the second while the first was the false one. A contradiction refutes the conjunction of everything assumed.

Problem 7

Prove that $\sqrt 2 + \sqrt 3$ is irrational.

Show solutionHide solution

Suppose, for contradiction, that $r = \sqrt 2 + \sqrt 3$ is rational. Squaring, $r^2 = 2 + 2\sqrt 6 + 3$, so $\sqrt 6 = \frac{r^2 - 5}{2}$, which is rational because sums, products and quotients (by nonzero numbers) of rationals are rational. So it is enough to show that $\sqrt 6$ is irrational. Suppose $\sqrt 6 = \frac{p}{q}$ in lowest terms with $p, q$ positive integers. Then $p^2 = 6q^2 = 2(3q^2)$ is even, so $p = 2k$ by the parity lemma. Then $4k^2 = 6q^2$, so $2k^2 = 3q^2$ and $3q^2$ is even. If $q$ were odd, $q^2$ would be odd and $3q^2$, a product of odd numbers, would be odd. So $q$ is even. Then 2 divides both $p$ and $q$, contradicting lowest terms. Hence $\sqrt 6$ is irrational, which contradicts the rationality of $\frac{r^2 - 5}{2}$, and $r$ is irrational.

Problem 8

Every odd prime has the form $4k + 1$ or $4k + 3$. Prove that there are infinitely many primes of the form $4k + 3$. (Hint: consider $N = 4p_1 p_2 \cdots p_n - 1$, and first show that a product of numbers of the form $4k + 1$ again has that form.)

Show solutionHide solution

Product fact. $(4a + 1)(4b + 1) = 16ab + 4a + 4b + 1 = 4(4ab + a + b) + 1$, so a product of two numbers of the form $4k + 1$ has that form, and by repeating, so does a product of any number of them.

Factoring into primes. Every integer $N > 1$ is a product of primes: by the prime factor lemma $N = pM$ with $p$ prime; if $M > 1$, apply the lemma to $M$, and so on. The quotients strictly decrease, so the process stops.

The proof. Suppose, for contradiction, that $p_1, \dots, p_n$ are all the primes of the form $4k + 3$ (the list is not empty, since it contains 3). Let $N = 4p_1 \cdots p_n - 1$. Then $N \geq 11$, and $N = 4(p_1 \cdots p_n - 1) + 3$ has the form $4k + 3$. In particular $N$ is odd, so every prime factor of $N$ is odd, hence of the form $4k + 1$ or $4k + 3$. If all of them had the form $4k + 1$, then $N$, their product, would have the form $4k + 1$ by the product fact. But $N$ leaves remainder 3 on division by 4. So some prime factor $p$ of $N$ has the form $4k + 3$, and by assumption $p$ is one of the $p_i$. Then $p$ divides $4p_1 \cdots p_n$ and $p$ divides $N$, so $p$ divides their difference, which is 1. No prime divides 1. This contradiction proves the claim.

Shared definitions used by this lesson's figures
# house kit: prepended to every essay figure after the std imports

# palette. AZURE and EMBER are the two actors, LEAF marks an answer, ROSE a problem
let PAPER = [1, 1, 1, 1]
let INK = [0.08, 0.09, 0.11, 1]
let SLATE = [0.40, 0.44, 0.50, 1]
let MIST = [0.85, 0.86, 0.88, 1]
let AZURE = [0.13, 0.42, 0.68, 1]
let EMBER = [0.89, 0.42, 0.12, 1]
let LEAF = [0.13, 0.55, 0.36, 1]
let ROSE = [0.78, 0.22, 0.24, 1]
let PLUM = [0.47, 0.30, 0.66, 1]
let GOLD = [0.85, 0.62, 0.08, 1]

background = PAPER

# an opaque pastel of col; use for fills so overlaps do not darken
let tint = |col, amount = 0.18| [
    1 - (1 - col[0]) * amount,
    1 - (1 - col[1]) * amount,
    1 - (1 - col[2]) * amount,
    1
]

# text: Cap for labels, Note for quiet labels, Math for typeset maths
let Cap = |txt, size = 0.75, col = INK| color{col} Text(txt, size, "Charter")
let Note = |txt, size = 0.65| color{SLATE} Text(txt, size, "Charter")
let Math = |tex, size = 0.9, col = INK| color{col} Tex(tex, size)

# a paper rectangle to sit behind text that crosses lines
let Plate = |pos, size| center{pos} fill{PAPER} stroke{alpha{0} PAPER, 0} Rect(size)

# shapes with fill and stroke both set, so no stray black appears
let Pt = |pos, col = INK, r = 0.075| center{pos} fill{col} stroke{col, 1} Circle(r, 48)
let Ring = |pos, col = INK, r = 0.1, w = 3| center{pos} fill{PAPER} stroke{col, w} Circle(r, 48)
let Seg = |a, b, col = INK, w = 3| stroke{col, w} Line(a, b)
let Path = |pts, col = INK, w = 3| stroke{col, w} Polyline(pts)
let Region = |pts, col| fill{col} stroke{alpha{0} col, 0} Polygon(pts)
let Outline = |pts, col = INK, w = 3| fill{alpha{0} PAPER} stroke{col, w} Polygon(pts)
let Shape = |pts, col, amount = 0.18, w = 3| fill{tint(col, amount)} stroke{col, w} Polygon(pts)
let Disc = |pos, r, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Circle(r, 96)
let Box = |pos, size, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Rect(size)
# a line from a to b ending in a small solid arrowhead
let Tip = |a, b, col = INK, w = 3, head = 0.17| {
    let d = normalize([b[0] - a[0], b[1] - a[1], 0])
    let n = [-d[1], d[0], 0]
    let base = [b[0] - d[0] * head, b[1] - d[1] * head, 0]
    return [
        stroke{col, w} Line(a, base),
        fill{col} stroke{col, 1} Polygon([
            b,
            [base[0] + n[0] * head * 0.42, base[1] + n[1] * head * 0.42, 0],
            [base[0] - n[0] * head * 0.42, base[1] - n[1] * head * 0.42, 0]
        ])
    ]
}

# plots. a frame is [x0, x1, y0, y1, centre, width, height]: a data window and the scene box it fills
let Frame = |x0, x1, y0, y1, c = [0, 0, 0], w = 6.4, h = 3.6| [x0, x1, y0, y1, c, w, h]
let fx = |fr, x| fr[4][0] + (x - (fr[0] + fr[1]) / 2) * fr[5] / (fr[1] - fr[0])
let fy = |fr, y| fr[4][1] + (y - (fr[2] + fr[3]) / 2) * fr[6] / (fr[3] - fr[2])
let at = |fr, x, y| [fx(fr, x), fy(fr, y), 0]

# axes through the data origin (or the nearest edge of the window), with optional names
let Axes = |fr, x_name = "", y_name = "", col = SLATE| {
    let ox = clamp(fr[0], 0, fr[1])
    let oy = clamp(fr[2], 0, fr[3])
    var parts = [
        Tip(at(fr, fr[0], oy), [fx(fr, fr[1]) + 0.25, fy(fr, oy), 0], col, 2.5, 0.15),
        Tip(at(fr, ox, fr[2]), [fx(fr, ox), fy(fr, fr[3]) + 0.25, 0], col, 2.5, 0.15)
    ]
    if (x_name != "") {
        parts .= center{[fx(fr, fr[1]) + 0.5, fy(fr, oy), 0]} Math(x_name, 0.8, col)
    }
    if (y_name != "") {
        parts .= center{[fx(fr, ox), fy(fr, fr[3]) + 0.5, 0]} Math(y_name, 0.8, col)
    }
    return parts
}

# tick marks with numbers at the listed data values
let XTicks = |fr, xs, col = SLATE, places = 0| block {
    let oy = fy(fr, clamp(fr[2], 0, fr[3]))
    for (x in xs) {
        . Seg([fx(fr, x), oy - 0.07, 0], [fx(fr, x), oy + 0.07, 0], col, 2)
        . center{[fx(fr, x), oy - 0.33, 0]} Math(to_string(x, places), 0.72, col)
    }
}
let YTicks = |fr, ys, col = SLATE, places = 0| block {
    let ox = fx(fr, clamp(fr[0], 0, fr[1]))
    for (y in ys) {
        . Seg([ox - 0.07, fy(fr, y), 0], [ox + 0.07, fy(fr, y), 0], col, 2)
        . center{[ox - 0.36, fy(fr, y), 0]} Math(to_string(y, places), 0.72, col)
    }
}

# faint grid lines at the listed data values
let GridLines = |fr, xs, ys, col = MIST| block {
    for (x in xs) {
        . Seg(at(fr, x, fr[2]), at(fr, x, fr[3]), col, 1.5)
    }
    for (y in ys) {
        . Seg(at(fr, fr[0], y), at(fr, fr[1], y), col, 1.5)
    }
}

# the graph of f over [a, b], drawn in the frame. values are clamped to the window
let Graph = |fr, f, a, b, col = AZURE, w = 4, n = 160|
    stroke{col, w} Polyline(map(sample(a, b, n), |x| at(fr, x, clamp(fr[2], f(x), fr[3]))))

# the region between the graph of f and the x axis over [a, b]
let AreaUnder = |fr, f, a, b, col = AZURE, amount = 0.2, n = 80| {
    var pts = [at(fr, a, 0)]
    for (x in sample(a, b, n)) {
        pts .= at(fr, x, clamp(fr[2], f(x), fr[3]))
    }
    pts .= at(fr, b, 0)
    return fill{tint(col, amount)} stroke{alpha{0} col, 0} Polygon(pts)
}

# a truth value tile: T is solid, F is hollow
let TV = |pos, v, col = AZURE, w = 0.7, h = 0.48, size = 0.8| [
    center{pos} fill{[PAPER, col][to_int(v)]} stroke{[SLATE, col][to_int(v)], 2.5} Rect([w, h]),
    center{pos} Cap(["F", "T"][to_int(v)], size, [SLATE, PAPER][to_int(v)])
]
let Col = |x, y0, dy, vals, col, w = 0.7, h = 0.48, size = 0.8| map(range(0, len(vals)), |r| TV([x, y0 - r * dy, 0], vals[r], col, w, h, size))
let FrameBox = |x0, x1, y0, y1, col, w = 4.5| Outline([[x0, y0, 0], [x1, y0, 0], [x1, y1, 0], [x0, y1, 0]], col, w)
# the running near miss: 17^2 = 289 against 2 * 12^2 = 288
let PP = 17
let QQ = 12
# a point and a rectangle on a grid of cells of side u with lower left corner o
let cpt = |o, u, i, j| [o[0] + i * u, o[1] + j * u, 0]
let Cells = |o, u, i0, j0, i1, j1, col, amount = 0.3, w = 3| Shape([cpt(o, u, i0, j0), cpt(o, u, i1, j0), cpt(o, u, i1, j1), cpt(o, u, i0, j1)], col, amount, w)
# tiles of side a and b cells in opposite corners of a square of side p cells whose corner is cell (c, c)
let Tiles = |o, u, c, p, a, b| block {
    if (a > 0.05) {
        . Cells(o, u, c, c, c + a, c + a, AZURE)
    }
    if (b > 0.05) {
        . Cells(o, u, c + p - b, c + p - b, c + p, c + p, EMBER)
    }
    if (a + b > p + 0.05) {
        . Cells(o, u, c + p - b, c + p - b, c + a, c + a, PLUM, 0.45)
    }
}
# one step of the descent
let down = |pq| [2 * pq[1] - pq[0], pq[0] - pq[1]]