legost.in Блог

Лабораторный журнал

Как устроен учебник «Математика» и как мы проверяем каждую формулу

Шестьдесят одна глава — от зарубок на кости до теорем Гёделя. Под текстом работают собственный математический движок, набор живых чертежей и семь слоёв проверки. Рассказываю, как это устроено и какие задачи пришлось решить, чтобы учебнику можно было верить: одна ошибка стоит доверия ко всему курсу.

Вячеслав Легостин 25 минут чтения

Модель швейцарского сыра: семь слоёв проверки, три ошибки, и каждая застревает в каком-то слое 1 2 3 4 5 6 7
Семь слоёв проверки. Ни один не закрыт наглухо, но сквозной дыры через все семь нет.
глава в 10 частях, на двух языках
61
тысяч слов русского текста, не считая формул
≈ 270
теоремы, леммы и следствия в выделенных блоках
694
доказательств-чертежей, которые строятся по шагам
313
виджетов глав, 59 тренажёров, 24 решателя
306
автотестов, и все зелёные
678

01

Что получилось

Учебник «Математика — царица наук» живёт на этом сайте и ничего не стоит. Он начинается с того, как люди научились считать, и доходит до того, чем математики заняты сейчас: теории меры, функционального анализа, теорем Гёделя, топологии, хаоса. Уровни — от пятого класса до старших курсов университета. Ориентиром для университетской части служили программы MIT, Кембриджа, мехмата МГУ и Независимого московского университета.

Главы нанизаны на одну нить. Каждая начинается со стены — задачи, которую прежними средствами не решить, — и заканчивается новой стеной, которую пробивает следующая глава. Через весь курс проходят семь больших вопросов. Почему минус на минус даёт плюс? Можно ли разрезать круг на куски и сложить из них квадрат? Почему для уравнения пятой степени нет формулы корней? Чего больше: натуральных чисел или точек на отрезке? Как работает шифр, который защищает ваш банк? Почему погоду нельзя предсказать на месяц вперёд? Может ли утверждение быть истинным, но недоказуемым?

При этом у каждой главы своя форма. «Простые числа» — охота, «Корень из двух» — детективное расследование, «Ноль и минус» — спор со скептиком XVII века, «Треугольник» — лаборатория из десяти опытов, «Счёт» — экскурсия по музею систем счисления. Формулы здесь можно трогать: нажмите на часть формулы — она подсветится и объяснит себя. Чертежи доказательств строятся шаг за шагом, а вершины треугольника можно тянуть пальцем и смотреть, что рассуждение не ломается.

0 · Что такое математика 0 Старт 1 · Счёт: от зарубок до битов 1 Счёт 2 · Ноль и минус 2 Ноль и минус 3 · Простые числа 3 Простые числа 4 · Делимость и алгоритм Евклида 4 Делимость 5 · Дроби 5 Дроби 6 · Корень из двух и действительные числа 6 Корень из двух 7 · Буквы вместо чисел 7 Буквы 8 · Уравнения: искусство равновесия 8 Уравнения 9 · Функции и графики 9 Функции 10 · Квадратные уравнения 10 Квадр. уравнения 11 · Системы уравнений и неравенства 11 Системы 12 · Степени и логарифмы 12 Логарифмы 13 · Последовательности и индукция 13 Последовательности 14 · Многочлены 14 Многочлены 15 · Комплексные числа 15 Компл. числа 16 · Начала: аксиомы и построения 16 Начала Евклида 17 · Треугольник 17 Треугольник 18 · Теорема Пифагора 18 Пифагор 19 · Окружность и число π 19 Окружность и π 20 · Площадь и объём 20 Площадь и объём 21 · Тригонометрия 21 Тригонометрия 22 · Векторы и координаты 22 Векторы 23 · Симметрия и преобразования 23 Симметрия 24 · Конические сечения 24 Конич. сечения 25 · Пределы 25 Пределы 26 · Производная 26 Производная 27 · Экстремумы и оптимизация 27 Экстремумы 28 · Интеграл 28 Интеграл 29 · Число e и экспонента 29 Число e 30 · Ряды 30 Ряды 31 · Дифференциальные уравнения 31 Дифф. уравнения 32 · Функции многих переменных 32 Много переменных 33 · Ряды Фурье 33 Ряды Фурье 34 · Комплексный анализ 34 Компл. анализ 35 · Матрицы как преобразования 35 Матрицы 36 · Метод Гаусса 36 Метод Гаусса 37 · Векторные пространства 37 Вект. пространства 38 · Собственные векторы 38 Собств. векторы 39 · Ортогональность, МНК и SVD 39 МНК и SVD 40 · Группы 40 Группы 41 · Арифметика остатков и шифры 41 Остатки и шифры 42 · Кольца, поля и коды 42 Кольца и поля 43 · Теория Галуа 43 Теория Галуа 44 · Дзета-функция и эллиптические кривые 44 Дзета и кривые 45 · Комбинаторика 45 Комбинаторика 46 · Графы 46 Графы 47 · Вероятность 47 Вероятность 48 · Случайные величины 48 Случ. величины 49 · Статистика 49 Статистика 50 · Цепи Маркова и информация 50 Цепи Маркова 51 · Логика и множества 51 Логика и множества 52 · Бесконечности 52 Бесконечности 53 · Строгий анализ 53 Строгий анализ 54 · Мера и интеграл Лебега 54 Мера 55 · Функциональный анализ 55 Функц. анализ 56 · Гёдель, Тьюринг и пределы доказательства 56 Гёдель и Тьюринг 57 · Топология 57 Топология 58 · Неевклидовы геометрии 58 Неевкл. геометрии 59 · Хаос и фракталы 59 Хаос и фракталы 60 · Передний край 60 Передний край

Карта курса

61 станция, 10 линий

Линии — части курса, станции — главы, пересадки — места, где идея из одной части работает в другой. Станции кликабельны.

  • IЧисла
  • IIАлгебра
  • IIIГеометрия
  • IVАнализ
  • VЛинейная алгебра
  • VIСтруктуры
  • VIIСлучай и данные
  • VIIIОснования
  • IXГоризонты
Нажмите на станцию — откроется глава. На телефоне карту можно листать вбок.

02

Четыре этажа

Снаружи учебник выглядит как страницы с текстом и картинками. Внутри у него четыре этажа, и каждый держится на нижних. Сломается движок — соврут и решатели, и тренажёры, и виджеты. Поэтому проверки, о которых пойдёт речь дальше, начинаются снизу.

  1. 4

    Платформа

    Адреса на двух языках, карта метро, словарь из 593 терминов, каталог тем, страница всех тренажёров.

    Laravel · PHP 8.3
  2. 3

    Содержимое

    61 глава, 24 решателя, 59 тренажёров. Виджеты главы грузятся только на её странице.

    HTML + модули JS
  3. 2

    Набор деталей

    Формула с разбором, доказательство-чертёж, поле ответа, тест, тренажёр, графики, геометрическая доска, 3D.

    Custom Elements · KaTeX
  4. 1

    Движок

    Точная арифметика, алгебра, уравнения, производные, интегралы, пределы, матрицы, теория чисел — с шагами на двух языках.

    ≈ 22 000 строк JS, без зависимостей

Первый этаж: движок, который считает дробями

Компьютер хранит обычные числа в двоичном виде, и знаков у них ограниченное количество. Одна десятая в двоичной записи — бесконечная дробь, как 1/3 в десятичной, поэтому в память она попадает слегка округлённой. Спросите почти любой язык программирования, сколько будет 0,1 + 0,2, и он ответит 0,30000000000000004.

Живой пример

Сложите две десятичные дроби

Обычная арифметика компьютера

0,30000000000000004

Движок учебника: дроби из целых чисел

3/10 = 0,3

А вот что на самом деле лежит в памяти вместо 0,1: 0,1000000000000000055511151231257827021181583404541015625.

На графике такой погрешности не видно. В учебнике она опасна: тренажёр сравнит правильный ответ ученика «0,3» с «0,30000000000000004» и засчитает ошибку. Поэтому движок хранит числа дробями, у которых числитель и знаменатель — целые числа любой длины (в JavaScript для этого есть тип BigInt). Одна треть остаётся одной третью, а 2100 — всеми своими тридцатью одной цифрой.

sin cos tg x
Так движок видит sin(cos(tg x)): функция внутри функции внутри функции. Производная идёт по этому дереву правилом цепочки, от корня к листьям, и каждый шаг записывается.

С формулами движок работает как с деревьями. По дереву можно идти правилами, как на бумаге, и каждое действие движок записывает шагом на двух языках: какое правило, что было, что стало и почему так можно. Из этих шагов собираются решения в решателях и разборы в тренажёрах.

Движок терпим к человеческой записи: понимает «2x», «sin 2x», «2(x + 1)», десятичную запятую, значки √ и π, модуль |x|. Он решает уравнения и неравенства с учётом области допустимых значений, системы, берёт производные, интегралы (каскадом из 18 методов) и пределы, работает с матрицами над рациональными числами, проверяет простоту тестом Миллера — Рабина и раскладывает числа на множители ρ-методом Полларда. Всё это — около 22 тысяч строк на JavaScript без единой внешней библиотеки.

Второй этаж: набор деталей

Над движком лежит набор из полутора десятков деталей, из которых собираются главы. Две самые заметные — разобранная формула и доказательство-чертёж. Ниже они настоящие, из главы 17 «Треугольник». Нажмите на часть формулы, а в доказательстве — «Дальше», и потяните вершины.

Теорема Сумма углов треугольника

Сумма углов любого треугольника равна 180°.

Угол при вершине $A$, на чертеже доказательства — $\alpha$. Угол при вершине $B$, на чертеже — $\beta$. Угол при вершине $C$, на чертеже — $\gamma$. Пример: если $\angle A = 50^\circ$ и $\angle B = 70^\circ$, то $\angle C = 180^\circ - 50^\circ - 70^\circ = 60^\circ$.

Хитрость в том, чтобы собрать все три угла у одной вершины.

Проведём через вершину $C$ прямую, параллельную стороне $AB$. Такая прямая существует, и она одна — это пятый постулат в форме Плейфера (глава 16). Угол между этой прямой и стороной $CA$ равен углу $A$: это накрест лежащие углы при параллельных прямых и секущей $AC$. Равенство накрест лежащих углов при параллельных — предложение I.29, первое, где Евклид применяет пятый постулат. По той же причине угол между прямой и стороной $CB$ равен углу $B$ — накрест лежащие углы при секущей $BC$. Между ними остался угол $C$. Три угла при вершине $C$ вместе заполняют развёрнутый угол, а он равен $180^\circ$. Значит, $\angle A + \angle B + \angle C = 180^\circ$.

Остальные детали попроще, но тоже опираются на движок. Поле «Попробуйте сами» проверяет ответ по смыслу: примет x + 1 и 1 + x, а если просили несократимую дробь, на 6/8 ответит «Верно, но дробь можно сократить». В тестах у неверного варианта бывает своё объяснение — почему ошибаются именно так. Тренажёры выдают бесконечный поток задач нескольких уровней, с подсказкой и разбором. Есть ещё графики с ручками, геометрическая доска и трёхмерные сцены.

Третий этаж: главы, решатели, тренажёры

Глава — это HTML-файл с шапкой: номер, часть, уровень, теги, какие главы стоит прочитать раньше. Решатель сначала читает задачу, как её написал бы человек — «x^2 − 5x + 6 = 0», «производная sin 2x», «20% от 350», — и показывает, как понял: «Понял так: …». Потом решает по шагам и объясняет, почему каждый шаг законен. Решателей 24, от дробей и процентов до дифференциальных уравнений. Тренажёров 59, у каждого свой генератор задач, своя проверка ответа и разбор.

Четвёртый этаж: платформа

Сверху — модуль сайта на Laravel. Он превращает внутренние ссылки вида ch:derivative#rules в адреса нужного языка, собирает словарь из определений в главах (593 термина, каждый определён ровно один раз), строит каталог тем по тегам и рисует карту метро. Маршруты линий на карте заданы вручную на сетке 64 × 36, а подписи станций расставляет программа: она знает ширину каждой буквы шрифта и перебирает положения подписей, пока ни одна не налезет на соседнюю или на линию.

03

Трудные места

На схеме всё выглядит стройно. Трудности начинаются там, где математика встречается с компьютером, с пальцем читателя и с двумя языками. Вот задачи, на которые ушло больше всего сил, и то, как они решены.

Ответ в любой форме

Люди пишут математику как придётся, и это нормально. Движок должен понять и «2x», и «sin 2x», и «2(x + 1)». Дальше начинаются тонкости.

  • Запятая. В русской записи это десятичный разделитель: 2,5. В английской запятая отделяет тысячи и элементы списка. Поэтому в русском режиме корни перечисляются через точку с запятой, «x₁ = −2; x₂ = 3», а в английском — через запятую.
  • Школьные соглашения. «1/2x» — это (1/2)·x, как в тетради, «log x» — десятичный логарифм, а два числа подряд, «2 3», движок считает ошибкой и не пытается угадать, что имелось в виду. По школьному правилу дробная степень определена только при x ≥ 0. Поэтому у уравнения x2/3 = 4 один корень, 8, а у ∛(x²) = 4 их два: ±8.
  • Верный ответ в неожиданном виде. Проверка сравнивает ответы по смыслу, а не по буквам: x + 1 и 1 + x для неё одно и то же, 0,5 и 1/2 тоже. Если просили несократимую дробь, на 6/8 она ответит «Верно, но дробь можно сократить». Тренажёр перевода между системами счисления узнаёт цифры, записанные в обратном порядке, и объясняет эту ошибку отдельно, а русскую «с», набранную вместо латинской «c» в шестнадцатеричном числе, прощает.

Анализ: где легко соврать

  • Интегралы. Одного алгоритма, который берёт все интегралы из учебников, не существует. Движок перебирает 18 методов: таблицу, замену переменной, интегрирование по частям, простейшие дроби, тригонометрические подстановки и другие. Любой найденный ответ он дифференцирует обратно и сравнивает с исходной функцией. Застревать движок умеет на мелочах: интеграл от 1/(1 + cos x) после подстановки t = tg(x/2) спотыкался о вложенную единицу в знаменателе, пока результат замены не стали приводить к несократимому виду.
  • Интегралы, которые сходятся еле-еле. У ∫0∞ sin x/x хвост колеблется бесконечно, и обычный численный метод не знает, где остановиться. Движок режет хвост по нулям синуса на «лепестки», складывает их, ускоряя сходимость усреднением Эйлера, и получает 1,570796…, то есть π/2. Если лепестки не уменьшаются, как у ∫0∞ sin x dx, интеграл расходится, и движок так и пишет. Особенность внутри отрезка он отделяет и считает отдельно: ∫02 dx/√|x − 1| = 4.
  • Правило Лопиталя. Его любят применять не глядя. Предел (x + sin x)/x при x → ∞ равен 1, а отношение производных, 1 + cos x, ни к чему не стремится, и наивная программа объявила бы, что предела нет. Движок применяет правило, только когда предел отношения производных существует.
  • Край области определения. Слева от нуля у x·ln x значений нет вовсе, и предел в нуле движок поначалу не находил. Теперь он замечает, что функция живёт только по одну сторону от точки, берёт односторонний предел, получает 0 и объясняет отдельным шагом, почему так можно.

Числа, которые не помещаются

  • Миллионы кандидатов. Рациональные корни многочлена ищут среди дробей p/q, где p делит свободный член, а q — старший коэффициент. У числа 735 134 400 целых 1344 делителя, так что для уравнения 735 134 400x⁵ − x − 735 134 400 = 0 пар p/q набирается больше миллиона. Честный перебор занимал 6,7 секунды. Теперь движок сначала находит корни приближённо, а точно проверяет только кандидатов рядом с ними: 3 миллисекунды.
  • Большие числа. Попытка разложить на множители 2128 + 1 длится больше секунды, и всё это время страница не отвечала бы. Поэтому числа больше 1014 раскладываются в фоновом потоке браузера. Простоту проверяет тест Миллера — Рабина: до 3,3·1024 он даёт точный ответ, дальше — вероятностный, и решатель говорит об этом прямо.

Картинки против плавающей точки

  • Галактика, которая съедает зазор. В главе 0 верёвку, удлинённую на метр, оборачивают вокруг Земли, теннисного мяча и Млечного Пути, и зазор везде около 16 см. Но радиус Галактики около 4,7·1020 м, а в числах с плавающей точкой R + 0,16 м равно в точности R. Виджет считает высоты от поверхности, иначе зазор у Галактики просто исчез бы.
  • Золотой угол, который не должен стать дробью. Подсолнух из главы 0 подписывает, на какую дробь оборота похож угол: 90° даёт 4 луча, 144° — 5. Золотой угол хуже всех чисел приближается дробями, и лучей у него нет. Но от дроби 21/55 он отличается всего на полторы десятитысячных оборота, и при щедром допуске виджет нарисовал бы 55 лучей там, где их нет. Допуск пришлось сузить до 1,5·10−6.

Золотой угол, 137,508°

21/55 оборота, 137,455°

Одни и те же 600 семечек, разница в угле — полторы десятитысячных оборота. Слева семена ложатся плотно, справа выстраиваются в 55 лучей с пустотой между ними.
  • Доказательство, которое можно тянуть. Чертёж доказательства — это функция от того, насколько нарисован каждый шаг. Поэтому «Назад», прыжок к любому шагу и перетаскивание вершин посреди анимации работают сами собой, без отдельного кода на каждый случай. На телефоне палец на чертеже прокручивает страницу, если не лёг на вершину. А вершина сдвигается только после 6 пикселей движения, иначе случайное касание портило бы картинку.
  • Тяжёлые страницы. В главе о треугольнике полсотни живых элементов, из них 27 доказательств-чертежей. Раньше на телефоне при открытии главы сразу создавалось 37 холстов для рисования, теперь ни одного: каждый появляется, только когда подъезжает к экрану.

Одна книга, два языка

  • Шестьдесят одна глава как одна книга. Главы связаны цепочкой стен, пишутся по общей таблице обозначений и ссылаются друг на друга. Каждый из 593 терминов определён ровно один раз, в той главе, где появляется впервые. В учебнике 694 теоремы, леммы и следствия, 26 аксиом и 643 доказательства: 313 чертежами, которые строятся по шагам, и 330 пошаговым текстом там, где честной картинки нет. «Примем без доказательства» разрешено только для результатов, которым нужны инструменты за пределами главы, вроде Великой теоремы Ферма. Тогда текст объясняет идею доказательства, на что оно опирается и почему целиком не помещается.
  • Две школьные традиции. Русский учебник пишет tg и ctg, английский — tan и cot. Интервал по-русски — (a; b), по-английски — (a, b). Даже общее решение sin x = a выглядит по-разному: в российской школе это одна формула с (−1)n, в английской — две серии корней. Движок пишет каждое решение в традиции читателя.
  • Решатели, которые понимают английский. Каждый пример из английских статей прогоняется через сам решатель. Чтобы примеры проходили, решатели научились формулировкам вроде «sketch the curve» и «a 20% discount», где направление скидки задаёт слово после числа.

04

Семь слоёв проверки

В авиации и медицине безопасность объясняют моделью швейцарского сыра, её предложил британский психолог Джеймс Ризон. Любая защита похожа на ломтик сыра: в ней есть дырки. Если сложить несколько ломтиков, дырки почти никогда не выстроятся в сквозной туннель, и ошибка застрянет на одном из слоёв. Картинка в начале статьи — как раз про это.

Проверки учебника устроены так же. Ни одной из них мы не доверяем полностью, но их семь, и они смотрят на ошибку с разных сторон. Главный принцип — второе мнение. Проверять ответ тем же способом, которым его получили, бесполезно: ошибка повторится и подтвердит сама себя. Поэтому почти каждая проверка идёт к ответу другой дорогой.

  1. 1Правила до первой строки
  2. 2Движок проверяет себя
  3. 3Автотесты: второе мнение
  4. 4Генератор против проверяющего
  5. 5Чертёж не должен врать
  6. 6Научное ревью
  7. 7Структура и язык
1

Правила до первой строки

Первая защита срабатывает до того, как текст написан. Черновики глав готовились с помощью языковых моделей, поэтому доверия по умолчанию у текста нет: у курса есть план на 1213 строк, где для каждой главы расписаны стена, форма, формулы, виджеты и проверенные факты, и правила для автора и рецензента. Правила начинаются с портрета читателя:

Он читает добровольно. Если станет скучно — закроет вкладку. Если найдёт ошибку — перестанет верить всему остальному.

из брифа автора главы

Дальше в правилах записано:

  • каждый численный пример пересчитать движком или отдельным скриптом; округлять честно: «≈ 1,414», а не «= 1,414»;
  • упростить изложение можно, упростить утверждение — нельзя: все условия теоремы на месте, будь то a ≠ 0, непрерывность на отрезке или взаимная простота;
  • для каждой формулы сказать, при каких условиях она верна и как ломается, если условие нарушить;
  • легенды называть легендами, цитаты давать только проверяемые, спорное — с оговоркой.

К каждой главе прилагается список фактов, в которых автор не уверен. В главе о квадратных уравнениях туда попало точное число задач на вавилонской табличке BM 13901. В тексте осталось осторожное «больше двух десятков». История о том, как Гротендик назвал простым число 57, в главе 3 подана как анекдот, прямо с пометкой «по известному анекдоту». А про Гиппаса, которого будто бы утопили за открытие иррациональности, в главе 6 сказано без обиняков: «Это легенда: надёжных свидетельств о ней нет».

2

Движок проверяет себя в момент ответа

Каждый ответ, который движок показывает читателю, он сначала проверяет сам, причём другим способом.

  • Производную он считает дважды: деревом правил, из которого получаются шаги решения, и отдельным быстрым расчётом. Результаты сравниваются, а потом сверяются с числами в шести точках. В коде это правило записано комментарием: never show a result that disagrees with the independent computation — никогда не показывать результат, который расходится с независимым расчётом.
  • Первообразную движок дифференцирует обратно и сравнивает с исходной функцией. Не совпало — ответа нет, а читатель видит сообщение: «Найденная функция не прошла проверку дифференцированием, поэтому ответа не показываем». Ещё тоньше: первообразная должна быть определена везде, где определена сама функция. Поэтому для 1/x ответ ln x отбрасывается, нужен ln |x|.
  • Корни подставляются в исходное уравнение и проверяются по области допустимых значений. Посторонние корни не исчезают молча: решатель показывает, откуда они взялись и почему отброшены.
  • Предел сверяется с таблицей значений функции во всё более близких к точке местах. Если числа с ответом не сходятся, ответ не показывается.
  • Когда движок не умеет, он так и говорит. Интеграл от ex² не выражается через элементарные функции, и движок называет специальную функцию erfi вместо того, чтобы выдумать ответ. Численный поиск корней помечает найденное значком «≈» и никогда не утверждает «корней нет» только потому, что их не нашёл.
Блок «Проверка» решателя интегралов: производная ответа tg(x/2) равна 1/(cos x + 1), и таблица численной проверки в трёх точках
Так самопроверка выглядит в решателе интегралов: ответ дифференцируется символьно, а потом наклон его графика независимо сравнивается с функцией в трёх точках.
3

Автотесты: второе мнение для каждого ответа

Код учебника проверяют 678 автотестов. Почти все построены по одному принципу: ответ движка сверяется с чем-то, что посчитано совсем иначе.

Движок считаетТест проверяет
производные 173 функцийнаклоном секущей через две очень близкие точки
218 первообразныхдифференцированием обратно; большие степени — точно, дробями, потому что плавающая точка их уже не различает
153 классических пределазначениями функции во всё более близких к точке местах
корни уравненийподстановкой и густым перебором: не пропущен ли корень
неравенствазнаком выражения в точках на прямой
комбинаторикуполным перебором всех вариантов
вероятностиперечислением всех исходов: кости, монеты, урны
определителинесколькими методами сразу, включая формулу Лейбница
собственные векторыпроверкой A·v = λ·v
решение треугольникаслучайный треугольник → его данные → решаем обратно
разложение на множителиперемножением обратно и проверкой, что все множители простые

Есть и тесты-хулиганы. Они подсовывают решателям полторы тысячи случайных строк, от пустых до бессмысленных, и требуют одного: ответа или вежливого сообщения об ошибке, но никогда не падения. Другие следят, чтобы упрощение, применённое дважды, ничего не меняло: упростил — и упрощать больше нечего. В ночь сборки это правило нарушалось примерно на двух процентах случайных выражений. После исправления — ни разу на 51 000.

Самый наглядный из этих приёмов — проверка производной секущей. Возьмите две точки рядом, x − h и x + h, и посчитайте наклон отрезка между ними на графике. Чем меньше h, тем ближе наклон к производной. До поры.

Живой пример · движок учебника

Лупа для проверяющего

Движок, символьно

f′(x) = …

f′(1,3) = 3,8808561912

наклон секущей
7,5986568494
ошибка
3,7
Ошибка ведёт себя как буква V. При большом шаге секущая срезает изгибы графика: при h = 0,1 она даёт 7,6 вместо 3,88. При крошечном шаге вступает округление: значения f(x + h) и f(x − h) совпадают почти во всех знаках, и их разность превращается в шум. Лучше всего — посередине, около h ≈ 10−6. Попробуйте свою функцию.

Проверяющего тоже приходится проверять. В ночь сборки численная производная самого движка для этой функции в точке 1,3 выдала 6,17 вместо 3,88: первый шаг перешагнул почти целую волну. При этом метод сам оценил свою погрешность в 1,6 — слишком много, чтобы ответу верить. Теперь он замечает такую оценку и начинает заново с шагом в 8, 64, … раз меньше, оставляя лучший результат.

4

Тренажёры: генератор против проверяющего

Тренажёр состоит из двух половин: генератор придумывает задачи, проверка оценивает ответы. Ошибка в любой половине бьёт по читателю: либо задача некорректна, либо правильный ответ не засчитают. Поэтому в тестах каждый из 59 тренажёров выдаёт по 300 задач на каждом уровне, всего 55 800 задач за прогон. Проверка обязана принять собственный ответ генератора, а все формулы — отрисоваться без ошибок.

Но собственный ответ генератора проверка примет всегда, даже неверный: она сравнивает ответ сам с собой. Поэтому нужен и второй взгляд — независимый пересчёт задачи из её условия. В общих тестах он есть, например, у тренажёров дробей и линейных уравнений, а авторы глав прогоняли через такие пересчёты свои тренажёры тысячами задач. Попробуйте сами: вот настоящий тренажёр дробей из главы 5.

Живой пример · тренажёр из главы 5

900 задач за секунду

Генератор выдаст по 300 задач на каждом из трёх уровней. Каждую проверяем дважды: принимает ли проверка ответ генератора и совпадает ли он с точным пересчётом условия.

проверка приняла свой же ответ
—
совпал с независимым пересчётом
—

Нажмите на клетку, чтобы увидеть задачу.

С подложенной ошибкой генератор портит числитель примерно в каждой пятидесятой задаче. Первая проверка этого не видит: она по-прежнему принимает все 900 ответов. Красные клетки находит только второе мнение.

Именно так нашлось, что около 6% задач тренажёра линейных уравнений на втором и третьем уровне имели корень 0, а общий знаменатель доходил до 1638. Теперь корень никогда не ноль, а знаменатели не больше 20. И в самой проверке ответов нашлась ошибка, которая отвергала правильные ответы: при разборе списка «3+sqrt(2)» теряло скобку и превращалось в «3+sqrt(2».

5

Картинки: чертёж не должен врать

Картинку проверить труднее, чем число: она может быть правильной в одном положении и лживой в другом.

  • Детали, из которых рисуются чертежи доказательств, в тестах прогоняются во всех моментах анимации, и нигде не должно появиться NaN — «не число». Авторы глав вдобавок прогоняли свои фигуры в десятках случайных положений ручек на каждом шаге.
  • Доказательства перекраиванием охраняет отдельный тест: деталь, которая двигает кусок фигуры, в любой момент анимации сохраняет длины и углы. Иначе картинка «доказывала» бы с помощью незаметной подгонки.
  • Каждую страницу снимает скрипт на экранах шириной 360 и 1280 пикселей, в светлой и тёмной теме. Он проверяет, что в консоли нет ошибок, а страница не прокручивается вбок, и умеет нажимать кнопки и тянуть ручки.
  • Рецензент тащит ручки в крайние положения. Так нашлась полоска «все суммы» в задаче о монетах 11 и 15: она обрывалась на 120, хотя самая большая невозможная сумма равна 11·15 − 11 − 15 = 139. Нашёлся чертёж деления с остатком, у которого при отрицательном делимом всё интересное уходило за край.
6

Научное ревью

Написанную главу читает научный рецензент. У него свой бриф и другая роль: «придирчивый научный редактор с математическим образованием уровня хорошего университета». Его задача — чтобы в главе не осталось ни одной ошибки.

Рецензент проверяет, все ли условия у теорем на месте. Он пересчитывает каждое число и каждое «≈», ищет дыры в доказательствах, сверяет имена, годы и цитаты. Виджеты он двигает в крайние положения и читает их вычислительный код, тренажёры прогоняет сотнями задач. Явные ошибки исправляет сам, стиль не трогает, а сомнения выносит в отчёт. Типичный итог рецензии на три главы: явных математических ошибок нет, одиннадцать уточнений формулировок, каждое число пересчитано, четыре тренажёра прошли независимую проверку по 600 задач на уровень.

Поверх рецензий идёт сквозная вычитка: главы с 12-й по 21-ю прочитаны целиком, остальные прошли фактическую проверку. Скрипт вытаскивал из текста даты, имена и числа, и каждое сверялось. Свежие события из последней главы — о переднем крае математики в 2026 году — сверялись с источниками через веб-поиск.

7

Структура и язык

Последний слой следит, чтобы учебник был единым целым. Тест структуры проверяет, что у каждой главы есть обложка и раздел «Куда дальше», ссылки ведут на существующие главы и якоря, каждый термин определён ровно один раз, каждый виджет из текста существует в коде, у каждого тренажёра есть генератор, а русская и английская версии используют одни и те же виджеты и разделы.

Язык проверяет скрипт-стилист. Он ищет штампы машинного текста и канцелярит — «является», «данный», «давайте разберёмся», «не просто…, а…», «играет важную роль», «удивительный мир» — и показывает каждое место. Над ним стоит правило из брифа: прочитайте абзац вслух; если так не говорят люди, перепишите.

Перевод на английский оказался ещё одной проверкой: переводчик читает каждую фразу медленнее любого редактора. Так нашлись неточности в русском оригинале: например, результат Теренса Тао о гипотезе Коллатца верен для «почти всех» чисел в смысле логарифмической плотности, и эту оговорку в русский текст добавили.

05

Досье пойманных ошибок

Вот что поймали проверки в первые сутки. Здесь не всё, а самое показательное. Зачёркнуто — как было, ниже — как стало.

Текст · глава 3 «Простые числа»

Ближе стоять не могут: из двух соседних чисел одно чётное.

…из двух соседних чисел одно чётное, а чётное простое только одно — двойка, так что соседями бывают лишь 2 и 3.

Речь о простых-близнецах: 3 и 5, 11 и 13, 41 и 43.

Слой 6 · научный рецензент

Текст · глава 3

Если в числителе и знаменателе по двадцать цифр, разложение превращается в долгую работу даже для компьютера.

Для двадцатизначных перебор делителей растянется на миллиарды делений, а числа в несколько сотен цифр не может разложить за разумное время даже компьютер.

Сам движок учебника раскладывает произведение двух 13-значных простых примерно за 0,3 секунды.

Слой 6 · научный рецензент

Текст · глава 3

Отношение π(x) к x/ln x стремится к единице — медленно, но неуклонно.

Медленно и не монотонно: от 102 к 103 оно даже подросло.

Текст спорил с таблицей из той же главы: 25/21,7 ≈ 1,151, а 168/144,8 ≈ 1,161.

Слой 6 · научный рецензент

Текст · глава 5 «Дроби»

Как найти самое короткое разложение, в общем случае неизвестно.

Самое короткое разложение можно найти перебором, но быстрого способа для него не знают.

«Неизвестно как» и «неизвестно, как быстро» — разные утверждения.

Слой 6 · научный рецензент

Движок · численный интеграл

∫1∞ dx/x = 37,29, погрешность 0,07.

Интеграл расходится, и движок теперь так и говорит: распознаёт медленный хвост, полюс внутри отрезка и колебания без затухания.

Слой 3 · при разработке движка анализа

Движок · численная производная

(sin(cos(tg x)))′ в точке 1,3 = 6,17.

3,8808…: при большой оценке погрешности метод начинает заново с меньшего шага.

Слой 6 · ревью движка

Движок · пределы

lim x·ln x при x → 0: ответа нет.

0, и отдельный шаг объясняет, почему предел берётся справа: слева от нуля логарифм не определён.

Слой 6 · ревью решателей

Движок · упрощение

(1/|x|)·(x/|x|) = x/x²

= 1/x. Упрощение, применённое дважды, больше ничего не меняет: 0 сбоев на 51 000 случайных выражений вместо примерно 2%.

Слой 3 · тест-хулиган

Картинка · решето Эратосфена

Нажимаете на 7: «7 — простое: ни 2, ни 3, ни 5, ни 7 его не делят».

«7 — простое: решето до него дошло, и никто его не вычеркнул».

Слой 6 · научный рецензент

Картинка · монеты Фробениуса

Полоска «все суммы» до 120.

Полоска до 160: для монет 11 и 15 самая большая невозможная сумма — 139, и её должно быть видно.

Слой 6 · научный рецензент

Тренажёр · линейные уравнения

≈ 6% задач с корнем 0, общий знаменатель до 1638.

Корень никогда не ноль, знаменатели не больше 20. Прогон на 9000 задач вырожденных не находит.

Слой 4 · независимый прогон

Тренажёр · проверка ответов

«3+sqrt(2)» → «3+sqrt(2» → неверно.

Список ответов режется с учётом глубины скобок, «(1 ± √5)/2» тоже читается правильно.

Слой 4 · проверка тренажёра

06

Чего проверки не гарантируют

Семь слоёв не делают учебник безошибочным. Они делают ошибку маловероятной, и у каждого слоя есть известные дыры.

  • Проверка в точках — не доказательство. Равносильность двух выражений движок устанавливает точно только для многочленов. Для остальных он сравнивает значения в 24 точках с точностью до 10−9. Совпадение в 24 точках почти наверняка означает тождество, но «почти» остаётся.
  • Некоторые красивые ответы движок узнаёт по числам. Что arctg(2 − √3) = π/12, он замечает потому, что значения совпали до десятого знака, а не потому, что вывел это символьно. Правда, он перепроверяет в обратную сторону: тангенс найденного угла тоже должен совпасть с 2 − √3. Без этой перепроверки arctg 1010 «узнавался» бы как π/2.
  • Тесты ловят только то, о чём мы догадались спросить. Ошибку, которую никто не вообразил, не поймает ни один тест.
  • История — самое слабое звено. Дату не пересчитаешь в node. Отсюда правило: только проверяемые цитаты, легенды называем легендами, спорное — с оговоркой.

Поэтому самый ценный слой — восьмой. Нашли ошибку — нажмите «Фидбэк» на странице курса.

С чего начать

Глава 0: пять коротких историй

Кот под верёвкой, подсолнух, который умеет считать, дракон из полоски бумаги, муравей, который строит шоссе, и сорок простых подряд. Каждая — с живой картинкой, которую можно трогать.

«Математика — царица наук, а арифметика — царица математики».

Так, по воспоминаниям Сарториуса фон Вальтерсхаузена, говорил Гаусс

Демо на этой странице работают на том же движке и тех же деталях, что и учебник, а её текст прошёл через тот же сканер штампов. Под капотом: Laravel, PHP 8.3, Vite, веб-компоненты на JavaScript, KaTeX 0.16, node:test, Pest и Playwright.