Ресурсы: техническое описание TLS, LaTeX - в картинки (img), криптографическая библиотека Arduino, шифр "Кузнечик" на ассемблере AMD64/AVX и ARM64
Кстати, в продолжение теоретико-числовых аспектов “Начал” Евклида. Смотрю тут книгу Бориса Трушина для школьников по теории чисел – “Теория чисел: с нуля до теоремы Эйлера”. На странице 66 там, под названием “Теорема Евклида”, приводится утверждение о том, что “простых чисел бесконечно много”, и доказательство – от противного: примем, что простых – конечное количество, перемножим их все, прибавим единицу, заметим, что результат не делится ни на одно из простых, – противоречие. Это типовое доказательство, которое встречается во многих учебниках. Почему приводят именно его – не очень понятно, но такова традиция. Однако, заметьте, в книге Трушина доказательство не названо “доказательством Евклида”. И это правильно. Почему? Потому, что Евклид-то доказывал данное утверждение не так. Евклид доказывал несколько более конструктивно.
Собственно, даже исходное предложение Евклида (9.20) сформулировано иначе: “простых чисел больше, чем в любом заданном (конечном) наборе простых чисел”. Может показаться, что это такая же формулировка, как и про “бесконечно много”, но, логически, это не так – Евклид не постулирует тут никакой бесконечности “от противного”, не рассматривает “все простые”, а использует конструктивный подход: даёте конкретный список простых чисел, и вот метод, по которому можно построить такое простое, которого не будет в этом списке. И доказательство у Евклида не от противного. Оно, что называется, более “конструктивное” (в той же мере, что и формулировка).
Логика исходного доказательства Евклида: выберем любые три простых числа A, B, C; возьмём наименьшее D, которое делится на A, B и C; прибавим к D единицу, получив число N = D + 1. (Обратите внимание, что единица здесь – это единица в евклидовом смысле, то есть, неделимый элемент.) Полученное число N либо является простым, которое не вошло в исходный список (утверждение, в этом случае, доказано), либо N – составное, и тогда N делится на какое-то простое (обратите внимание на этот момент – к нему ещё вернёмся ниже). Обозначим простое число, на которое делится N, буквой M. Если M – число из исходного списка [A, B, C], то M делит и D (по построению D). Следовательно, раз M делит и N, и D, то оно делит и разность N – D, но эта разность есть единица, и M не может её делить. Следовательно, M не входит в исходный список [A, B, C] – мы нашли новое простое число. То есть, тут показан достаточно конкретный способ конструирования нужных чисел, и это совсем другая история, чем постулирование “актуальной” бесконечности. Тем не менее, в учебниках регулярно приводят именно “доказательство от противного”, хоть оно и не является доказательством Евклида.
В доказательстве “от противного” фигурирует произведение всех простых. Если забыть, что это произведение всех простых, то нетрудно сделать ошибочный вывод, что можно всегда получить простое число, перемножив несколько последовательных простых и прибавив единицу. Это неприятный момент неверного обобщения результата, который полностью отсутствует в исходном доказательстве Евклида (см. выше). То есть, например, 2*3*5*7*11 + 1 = 2311 (простое), но это не означает, что просты и все такие числа (которые называют числами Евклида). Надо сказать, что в книге Трушина, как раз, сразу же, после доказательства теоремы Евклида этот, – наверное, самый важный, – момент подробно рассмотрен и показано, что уже 2*3*5*7*11*13 + 1 = 30031 = 59 * 509.
Книгу Трушина, кстати, порекомендую (и далеко не только школьникам). Там, конечно, есть несколько наивный небольшой раздел про применение теории чисел в криптографии, написанный, почему-то, на примере RSA, для которой проводится странное “сращивание” с шифрами простой замены. Это при том, что, конечно, RSA возникла из совсем другой задачи – из задачи распределения ключей, – а не из задачи зашифрования информации: для зашифрования были известны и абсолютно стойкий симметричный шифр, и симметричные же “комбинаторные” шифры, обладающие высокой стойкостью; более того, и наивный “побуквенный” шифр замены можно сделать очень стойким, пусть и простым в применении (возьмите колоду карт, скажем, и книгу). Но это всё специальные детали, которые я не смог пропустить в силу тематики dxdt.blog. И, конечно, к данному разделу в книге поставлена сноска, в которой прямо указано, что реальное применение RSA – сложнее, и совсем не такое, как описано. Так что, на содержательную часть – не влияет.
Комментировать »
Небольшое воскресное чтение манускриптов. Точнее – рассматривание чертежа из “Начал” Евклида, в версии манускрипта Vat.gr 190 девятого века. Это чертёж к Предложению 20 девятой книги, то есть, к доказательству того, что количество простых чисел больше, чем их есть в любом наперёд заданном (конечном) списке.

На чертеже почти все величины, используемые в доказательстве Предложения, обозначены отрезками одинаковой длины. Это довольно странно, а отчасти – загадочно, но именно так на старых манускриптах даны почти все чертежи для теоретико-числовых Предложений из “Начал”.
Другими словами, в доказательстве здесь используется три различных простых числа – ΑΒΓ, – это натуральные числа, но на рисунке их величины обозначены отрезками одинаковой длины. Причём, в более или менее современных переводах – отрезки на чертеже уже будут разными: очевидно, что трём разным натуральным числам не могут соответствовать отрезки одинаковой длины; ну, если только не считать эти отрезки совсем абстрактным представлением – тогда, конечно, длина на чертеже не важна: не рисуют же прямые углы, скажем, как строго прямые (вообще невозможно нарисовать прямой угол).
ΕΔ здесь – это отрезок, измеримый Α, Β и Γ, то есть, если на современный лад, произведение ΑΒΓ, а ΔΖ – единица (в евклидовом смысле), которая добавляется к ΕΔ, что даёт ΕΖ. Ну а Η – это отрезок, обозначающий простое число, которое измеряет ΕΖ (делит). И опять – одинаковой длины с ΕΔ.
Комментировать »
Открытый серверный ключ TLS, который указан в TLS-сертификате, на dxdt.blog начинается с подстроки DEADC0DE (в шестнадцатеричной записи, см. скриншот ниже).

Да, тут присутствует ещё и байт со значением 04 в самом начале, но он не имеет отношения непосредственно к ключу – это лишь указание на формат представления. 04 обозначает несжатую форму записи, когда прямо указываются две координаты точки ключа. Поэтому 04 можно отбросить. Такое значение ключа я использовал специально (это то, что называется vanity keys).
Как это значение получено? Оно получено перебором, конечно. Это не очень сложно сделать. Открытый ключ ECDSA – это точка на кривой. Точке соответствуют две координаты, одна из них (обычно, обозначают X), записывается слева. Поэтому в начале записи ключа будут идти старшие байты X-координаты. Остаётся подобрать такой секретный ключ, который даст открытый с нужной X-координатой. Секретный ключ – это натуральное число, больше двух и меньше порядка группы точек кривой (обычно, меньше тоже на два, но это детали). Нужно перебирать секретные ключи и проверять значение начальных байтов X-координаты открытого на соответствие заданной маске.
Открытый ключ – это точка-генератор G из параметров кривой, умноженная на значение секретного ключа d: [d]G. Я, используя готовую библиотеку из дистрибутива языка Go, написал быструю программу умножения на P-256 (кривая, которая используется здесь в ECDSA). Программа перебирает секретные ключи и делает это параллельно, во много потоков. Соответственно, даже на старом 16-потоковом процессоре AMD Ryzen 7, подбор ключа занял всего несколько часов. В результате подбора я получил нужный секретный ключ, который экспортировал для генерирования CSR (запрос на выпуск сертификата) и штатным способом использую при заказе TLS-сертификатов.
Вообще, для P-256 можно придумать немало открытых ключей, запись которых, в X-координате, выглядит ещё более необычно. Например:
0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBA - цифры A и немного B, 0x1000000000000000000000000000000000000000000000000000000000000001 - единицы и нули, 0x5000000000000000000000000000000000000000000000000000000000055555 - пятёрки и нули, 0x7777777777777777777777777777777177777777777777777777777777777777 - семёрки с "неожиданной" единицей, 0x8888888888888888888888888888881888888888888888888888888888888888 - восьмёрки, но тоже с единицей.
Точки с такими X-координатами лежат на кривой P-256. Определить для них Y-координату – не представляет вычислительной проблемы. Более того, ввиду свойств данной кривой – все эти точки, действительно, являются открытыми ключами. Тут есть лишь одна проблема: по открытому ключу очень сложно, а на практике – невозможно, вычислить секретный ключ; потому что это и есть основная задача, обеспечивающая стойкость ECDSA. Конечно, подходящий секретный ключ можно угадать. В том числе, в результате перебора. Вот только перебрать даже половину от, примерно, 2^256 – нереально. Ну и записать подходящий секретный ключ просто по наитию, как поступил бы борелевский шаман, пока что тоже не вышло. Так что придётся, до поры до времени, обойтись без забавных записей, ограничившись hexspeak-вариантом с DEADC0DE. Но как только и если появится квантовый компьютер подходящей разрядности, тогда можно будет секретные ключи подобрать очень быстро.
Комментарии (2) »
Для интересующихся английским языком и математикой (при чём тут математика – будет понятно ниже): на сайте The Guardian весьма занимательная задача – нужно прочитать известные идиомы и крылатые фразы на английском, но записаны эти фразы и идиомы в виде наборов цветных прямоугольников, где размеры прямоугольника соответствуют начертанию буквы, а цвета – разные для гласных и согласных (зелёный – гласные). Например, вот так, как на картинке ниже (взято из исходной статьи).

Предложения местами сложные, однако некоторые – угадываются довольно быстро (например, первая фраза). Мне удалось прочитать все 10 (надеюсь, что правильно – ответов, на момент публикации этой записки, ещё нет), так что механизм точно работает, попробуйте.
Там есть цитаты из Шекспира, да и сами исходные тексты, конечно, характерны, так сказать, для британского “литературного бэкграунда”, но это очень интересно, поскольку на конкретном примере показывает, насколько важна графическая форма слова в записи и графические же отношения между словами – а это уже чисто математический аспект.
Казалось бы, это идеальная задача для ИИ/LLM. Современная ИИ/LLM, которая, якобы, на “уровне золотой медали Международной математической олимпиады”, должна легко такую задачу решить. Ведь эти системы “обучены” на огромном корпусе текстов, в котором упомянутые фразеологизмы встречаются постоянно (ну, как бы, “Весь мир – театр” и “Не всё то золото, что блестит” – куда же чаще?). Я, конечно, загрузил текст и картинку с задачкой в ChatGPT современной версии. Откровенно говоря, я, при всём моём скептическом отношении, думал, что хотя бы с парой фраз система справится. ChatGPT не угадало ни одной фразы. Так что задача даже лучше, чем можно подумать.
Комментарии (6) »
Воскресное чтение манускриптов. Продолжаем несколько беспорядочное чтение предисловия из “Арифметики” Диофанта. В версии манускрипта 13 века Vat.gr.191 из Ватиканской Апостольской библиотеки. В прошлый раз – изучали фрагмент про “минус на минус” и обозначение “отрицательных” величин. В этот раз – вернёмся немного назад и прочитаем про два других обозначения: про “число”, как “Число” и про “монаду” (почти как в языке Haskell).
Мы раньше уже встречались с обозначением степеней (неизвестной) у Диофанта, и там был “кубо-кубос” (κυβόκυβος – ΚΥΚ ) для шестой степени – то есть, “куб плюс куб”. Там же был и квадрат – “дунамис” (“динамис”). Случай, когда никакой степени при неизвестной нет, – это, в современных обозначениях, просто x, – Диофант описывает отдельно.

В манускрипте написано: “Не получившее никакого названия [степени], но содержащее в себе неопределённое количество единиц, Числом (ἀριθμός) назовём, и пусть его обозначение – ς”.
Однако обозначение ς, “сигма” тут – весьма условное: знак только похож на сигму, но это точно не сигма. Так, на данном манускрипте вообще-то используется некий S-образный знак с волной и кружочком, он в середине скриншота, а увеличенный фрагмент – дан ниже.

В разных источниках этот знак переменной тоже разный. Кроме “похожего на сигму”, как здесь, встречаются: Ч-подобный знак, разные “волны с точками и кружками”, иногда иные варианты (дзета и т.д.). Очень загадочный знак. Непонятно, откуда он взялся, если не из сокращения слова ἀριθμός, тем более, что такая логика хорошо укладывается в схему именования других объектов Диофантом, как “кубусы” с каппой и т.д. (см. например, T. L. Heath. Diophantus of Alexandria).
Да и на рассматриваемом здесь манускрипте Vat.gr.191 нетрудно заметить, что вместо этого странного значка, далее по тексту, часто используется как раз скорописное сокращение для слова ἀριθμός. Так что, вполне возможно, что обозначение неизвестной в первой степени и у исходного Диофанта – это ни “сигма”, ни ещё какая-то буква, а специальный знак для слова “арифмос” (откуда, понятно, происходит “арифметика”).
Теперь к монадам. Вторая часть выделенного на скриншоте текста (после странного “сигма-знака” для “арифмоса”) – это описание и название для свободного коэффициента. То есть, для константы, которая входит в уравнение, соотвествующее той или иной задаче. Константы нужно отличать от переменных: “Другой знак для неизменяемого и определённого количества единиц будет “Μ”, несущая “Ο” сверху: M̊” – написано у Диофанта. Диофант задаёт при помощи этого обозначение контекст вычислений. Не сомневайтесь – тут прямо противопоставлены “переменные” и “константы”, в соседних предложениях. Это “мю” (Μ) в обозначении свободного коэффициента – первая буква слова μονάς – “монас”/”монада”. Монада используется у Диофанта именно в смысле выделенного инструмента, позволяющего понятийно отделить место для числа, от самого числа, при преобразованиях. Если вы подумали, что монадой, по принципу использования, тут является “арифмос”, как переменная, то это не так – у Диофанта понятия вводятся из соображений выделения отличий между преобразованиями. Поэтому и степени переменной обозначаются разными именами: “динамис”, “дианамо-динамис”, “кубо-кубос”, а не как принято сейчас – коэффициентом при обозначении неизвестной. Поэтому монада тут нужна именно для фиксирования преобразования. Ну, то есть, сейчас бы, на техничном языке, сказали бы, что это “функториальный инструмент”. Почти что как монада, используемая для обёртывания, например, операций ввода в Haskell. Да и название совпадает, что, конечно, естественно: сам термин “монада” – образован от древнегреческого слова.
Некоторое время назад мы уже находили на манускриптах древние знаки “дипле”, которые сейчас используются с той же целью – для обозначения цитируемого фрагмента текста в сообщении электронной почты, например. В этот раз – в тексте Диофанта используется монада, причём, в том же понятийном ключе, как и в современном языке программирования Haskell, но не только там.
Комментировать »
Уравнение Бомбелли – это кубическое уравнение . Рафаэль Бомбелли – итальянский инженер-математик 16 века. Он занимался гидротехникой. В том числе, масштабными проектами по осушению заболоченных лугов. Но в истории математики Бомбелли известен главным образом как автор трактата “Алгебра”, в котором, кроме прочего, описал объект, называемый сейчас “мнимой единицей”. Именно на примере упомянутого кубического уравнения, Бомбелли в “Алгебре” показывает, как найденные им “радикалы особого (другого) вида” можно применить для разрешения противоречий, связанных с “отрицательным числом под радикалом” в формуле Кардано.
Мы решим это знаменитое (в узких кругах) уравнение несколькими способами, выведем формулу Кардано, разберёмся, бывают ли “корни из отрицательных чисел”, поймём, откуда именно проблемные сочетания с минусом берутся в формуле Кардано, и что именно это означает, если отвлечься от бравурных заявлений вида “квадратные корни из отрицательных чисел существуют, но вам об этом не рассказывают”. А кроме того, определим, почему формула Кардано обычно бесполезна с практической точки зрения.
(Это немного дополненная версия статьи, которую я ранее опубликовал на “Хабре”.)
Читать полностью
Комментировать »
Воскресное чтение манускриптов. Продолжаем читать фрагменты “Арифметики” Диофанта, в изложении манускрипта 13 века Vat.gr.191 из Ватиканской Апостольской библиотеки (пока ещё до сайта библиотеки есть доступ). Манускрипт на древнегреческом. В прошлый раз изучали, как обозначаются степени (неизвестной) при помощи букв Δ и Κ на том же манускрипте. В этот раз – предложение про “отрицательность” и “положительность”. Как говорится, “минус на минус даёт плюс”. Как ни странно, но буквально это и написано в данном манускрипте, на следующей странице после определения записи степеней. А именно – см. скриншот ниже (я выделил соответствующий фрагмент).

Здесь сразу пара занятных моментов.
Во-первых, Диофант не использует концепцию отрицательных и положительных чисел в полном смысле, как это описывали бы сейчас, то есть, при помощи понятия обратных по сложению чисел, сумма которых равна нулю. Зато у Диофанта есть понятие “дефицит” (“нехватка” – там в женском роде, но это неважно), которое обозначается словом λεῖψις, и обратное к “дефициту” понятие – “достояние”, которое обозначается словом ὕπαρξις (здесь, видимо, в общем значении – “существование”, но в смысле – “имущество”, а именно, “то, что есть”).
Это, как бы, “убыток” и “наличие”, но, вообще-то, – эквивалентны “минусу” и “плюсу”. И вот здесь, во фрагменте со скриншота, Диофант пишет, что “дефицит на дефицит умноженный, даёт достояние, а дефицит на достояние – даёт дефицит”. То есть, буквально, “минус на минус – даёт плюс”, а “минус на плюс” – даёт минус.
Во-вторых, здесь же вводится обозначение для “дефицита” – в виде некоторого символа, типа “шалаша” из трёх чёрточек, который сейчас принято обозначать “𐅢” – если на вашем устройстве не отображается, то это такая вот усечённая “индейская национальная изба”, как в известном советском мультфильме. Однако в тексте с манускрипта эти три чёрточки интерпретируются несколько иначе. То есть, сам фрагмент с манускрипта (конец третьей подсвеченной строки, в современной типографике, без знаков препинания): “καὶ τῆς λείψεως σημεῖον Ψ ἐλλιπὲς κάτω νεῦον 𐅢”. Это переводится так: “и дефицита обозначение – Ψ, урезанное, вниз обращённое: 𐅢”. Однако данный фрагмент выглядит странным: зачем переворачивать и усекать пси? Так что данный кусочек мог быть дописан к исходному тексту в качестве пояснения, кем-то из сотрудников скриптория, а в исходнике Диофанта его не было.
Тут не нужно забывать, что манускрипт-то – 13 века, но исходный текст старше на тысячу лет, или около того, поскольку период деятельности Диофанта Александрийского – это третий век. Дописать пояснение могли раньше, не в 13 веке. Но всё равно, на момент дополнения текста, исходнику могло быть несколько веков. Смысл пояснения про “пси-переворот” в том, что странный знак нужно было описать текстом, для тех, кто будет переписывать манускрипт позднее. Забавно, но, буквально, та же история, как и в предыдущем абзаце, где я попытался описать символ словами про индейскую избу, на тот случай, если символ не отображается на вашем устройстве.
При этом сам Диофант, предположим, использовал просто некий вариант Λ с дополнительной “ногой”, потому что Λ (лямбда) – это первая буква слова λεῖψις, но чистую лямбду сложно отличить от обозначения числа 30 (см. например, T. L. Heath. Diophantus of Alexandria. Cambridge, 1910). Довольно интересная трактовка.
И, кстати, странные закорючки в начале первой и второй строки фрагмента на скриншоте выше, это скорописное сокращение слова ἐπί, кто бы мог подумать: см. скриншот ниже.

Слово встречается много раз, в том числе, на скриншоте, а сокращение – содержит все диакритические знаки из современной типографики, если приглядеться.
Комментировать »
Известная шутка гласит, что категорий людей – 10: одни уже знают двоичную систему счисления, а другие – ещё нет. Занятно, что 102 обозначает простое число – два. Это большая редкость в системах счисления, которые рутинно используются в ИТ. Понятно, что ни в восьмеричной, ни в десятичной, ни в шестнадцатеричной, 10 (как запись) не может обозначать простое число (как и всякая запись, заканчивающаяся на 0). А в двоичной – пожалуйста.
Естественно, это возможно только потому, что основание двоичной системы – простое число два. Если взять любое другое простое основание, то 10 тоже будет простым, потому что это и есть запись основания: три – по основанию 3, пять – по основанию 5, семь – 7, и так далее. Но наиболее привычны, кроме десятичной (десятеричной), это двоичная, восьмеричная и шестнадцатеричная.
Возьмём запись 11. В двоичной – это простое число три (112 = 2 + 1 = 3). В восьмеричной – девять, составное, но квадрат простого: 3^2. Та же запись 11 означает одиннадцать в десятичной, простое. Шестнадцатеричное 11 – это семнадцать, тоже простое.
Использование в этом ряду двоичной системы ограничивает доступный набор цифр: только 0 и 1. Но можно взять, например, 101 – трёхзначное:
это пять в двоичной (простое);
шестьдесят пять – в восьмеричной, составное: пять на тринадцать;
сто один – в десятичной, простое;
двести пятьдесят семь – в шестнадцатеричной, простое.
Обратите внимание, что запись чисел словами – это инвариантная, относительно системы счисления, запись.
1112 = семь (простое);
1118 = семьдесят пять (составное);
11110 = сто одиннадцать (простое);
11116 = двести семьдесят три (составное: 3*7*D).
Не забывая о том, что все простые числа, кроме числа два и числа три, имеют вид 6*n +/- 1, на трёх цифрах можно и остановиться. Тем более, что шестеричная система счисления не является распространённой.
Комментировать »
Сейчас практически постоянно пишут и говорят про “ИИ в математике”. Типа, какие “достижения”. Понятно, что инструмент перебора – может доставать какие-то доказательства кусками из ранее опубликованных работ, “синонимизировать” их, собирать из них другие доказательства и прикреплять к “нерешённым задачам”, например, из списков Эрдёша (где относительно много довольно простых, для специалиста, задач). Такой поиск перебором даже может быть полезен (но по модулю избыточных ресурсов, конечно).
Перебор – перебором, но LLM-перебор – это совсем не тот перебор, который вполне себе является методом математического доказательства. Например, как метод доказательства, перебор позволяет быстро находить контрпримеры к каким-то утверждениям. Элементарная иллюстрация: допустим, кто-то говорит, что нельзя “квадрат разложить на два квадрата”; это легко опровергнуть, просто “подобрав” самую известную пифагорову тройку: 3^2 + 4^2 = 5^2. Естественно, компьютеры существенно улучшили возможности по перебору: несравнимы возможности современного ПК и даже таких признанных вычислителей, каким был Эйлер. Однако всё это без учёта новомодных LLM, в которых, похоже, вычислительный ресурс в основном расходуется впустую.
А вот насколько точны результаты компьютерной обработки, применительно к теоретической математике, и как их интерпретировать – вопрос довольно сложный, скорее философский. По крайней мере, проблемы возникают с действительными числами, которые для компьютеров недоступны в принципе. Хуже того, несмотря на большую мощность, компьютер в принципе не может заглянуть даже в область действительно больших натуральных чисел. Но это всё сложные моменты, которые ничуть не отменяют того факта, что компьютеры давно влияют на теоретическую математику. И дело тут ни разу не в модных LLM.
Вообще, интересующимся темой, я бы порекомендовал серию прекрасных статей Н. А. Вавилова, которая начала выходить ещё в 2020 году, до всего этого “хайпа” с LLM “в математике”, и к LLM никакого отношения не имеет: “Компьютер как новая реальность математики” – вот где действительно есть тематическое содержание.
Комментировать »
Пустое множество принадлежит к набору фундаментальных объектов современной математики. И не только математики: в чистой философии – значение пустого множества едва ли не выше. Поэтому-то постоянно множатся и роли, которые пустое множество играет в куда более прикладных областях, чем теоретическая математика и философия: в информационных технологиях, да и в технике вообще.
Главное свойство пустого множества в том, что такое множество – единственно. То есть, у нас могут быть множества, собранные из разных объектов, но пустое множество – всегда одинаковое. Более того – это одно и то же множество, вне зависмости от “объектов” и типов. Пустое множество ананасов совпадает с пустым множеством апельсинов по слишком многим характеристикам, чтобы считать, что множества ананасов и апельсинов “пусты” разным образом, как и множество фруктов вообще.
Но, конечно, полностью отказаться от того, что “существуют” и пустое множество апельсинов, и пустое множество ананасов – довольно трудно: вот, только что была введена некоторая различительная окраска – ананасы против апельсинов. Например, если для приготовления блюда требуется ананас, то отсутствие апельсина – никак на кулинарную ситуацию не влияет, тогда как нехватка ананаса делает приготовление невозможным. Однако пустота тут, как концепция, общая. Да, нужно различить понятия “пустота” (“тип”) и “быть пустым” (“стрелка”), но стоит поднять пустоту в ничто, как начинает играть тот фактор, что и ничто, в представлении, бывает белое и чёрное.
Особенности естественного языка, позволяющие оборачивать отсутствие элементов в пустом множестве в размытое значение слова “ничего”, создают тем самым возможность для построения разных силлогизмов из пустого множества. Наверное, самый известный из них – про бутерброд (в вольном переводе): “Что лучше, чем вечное счастье? Ничего! Однако, один бутерброд – заведомо лучше, чем ничего. Следовательно – бутерброд лучше вечного счастья” (R. Smullyan/D. Darling). Здесь, естественно, объяснение в том, что в первой части описывается отсутствие объектов, которые лучше данного: таких объектов, утверждается, пустое множество; а потом, на бутербродном шаге, сравнение производится в обратную сторону: бутерброд заведомо лучше состояния, когда бутерброда нет (не отсутствия объектов, а самого пустого множества). То есть, это разные операции, но то, что пустое множество всего одно, позволяет подменять одну операцию другой.
Например, мне однажды переслали распечатку пары значений вывода утилиты sha256sum, на вход которой подавался результат работы модуля ec из пакета openssl (через “пайп” в консоли). При этом в openssl направлялись два разных файла. Утверждалось, что эти два входных файла содержат одинаковые данные, но только записаны данные в разной форме. Почему? Потому, что равны результаты sha256sum от выдачи openssl. Значения sha256sum, действительно, были равны, несмотря на то, что в openssl передавались разные файлы с разными именами.
Что же произошло на самом деле? Вот что. Утилита sha256sum считает значение хеш-функции SHA-256 от входных данных. Здесь на вход sha256sum поступал вывод openssl ec. Но, ещё раз, если значения равны, то, видимо, тогда и входные файлы содержат одинаковые данные? Нет – одинаковым тут является вывод openssl ec: дело в том, что оба входных файла имели неверный формат, поэтому модуль ec не мог их разобрать и печатал сообщение об ошибке, однако в стандартный вывод – писал пустое множество байтов; то есть, ничего не писал, проще говоря. А значения SHA-256 совпали потому, что на вход хеш-функции поступило пустое множество. А оно – одинаковое, вне зависимости от того, как именно сломался каждый из входных файлов.
Множества, состоящие из элементов разных типов, могут не сочетаться по типам, но пустое множество – сочетается со всеми типами. Когда нет апельсинов и ананасов, шестерней и транзисторов – то, с одной стороны, нет вещей разных типов, но, с другой стороны, общим тут является то, что их нет. Это сплошь и рядом используется в языках программирования.
Скажем, пустое множество возвращается в качестве признака того, что функция завершилась с ошибкой: это хорошо известный объект, обозначаемый nil, null, “” – ещё как-то. Обратите внимание, что значение null оказывается чем-то вроде пустоты, которая может быть помещена в коробку (да, именно так). Но null – это ещё не пустая коробка, как ни странно. В программировании, чтобы null стал “пустой коробкой”, этот null придётся как-то дополнительно трактовать: предположим, использвать null как указатель и попробовать обратиться по его значению (выполнить “дереференс”). Ошибочное толкование пустого множества в случае null и программного кода регулярно приводит к возникновению уязвимостей в ПО, в том числе, в весьма неочевидных случаях.
Современное обозначение для пустого множества – ∅ – появилось относительно недавно, в 30-х годах прошлого века. Но вполне возможно, что саму концепцию систематическим образом впервые строил Джордж Буль, в 1847 году. Впрочем, соответствующая концепция у Буля относится к логике и больше похожа на противопоставление “ничего” – которое есть “нуль”, 0, – “всему”, единице, 1.
Есть более интересное развитие определения: через количество объектов, которые не “само-эквивалентны” (Готлоб Фреге). Здесь “само-эквивалентность” – это обобщение свойства рефлексивности, то есть, когда A = A по свойствам операции, а именно, каждый объект эквивалентен самому себе. Тогда пустое множество – это те объекты, которые не эквивалентны самим себе. Казалось бы – таких объектов просто нет. Но чтобы заявить о том, что чего-то нет, придётся определить это “что-то”, чтобы описать и проотрицать существование, и на этом пути магу легко попасть в ловушку: попытка определения того, чего нет, введение типов, может вызвать данный “зомби-объект” к существованию – он, внезапно, “станет быть” или “будет есть” – как там правильно? А вот способ “не-само-эквивалентных” объектов – позволяет выполнить такое определение без излишней типизации и “зомби”. Ну, в каких-то пределах. Так, в DNSSEC подписывается цифровой подписью факт отсутствия записи – делается это при помощи погружения “отсутствия” в искусственный “пустой интервал” между соседними существующими DNS-записями, иногда такое погружение происходит замысловатым образом.
Не так уж редко используется и свойство пустого множества быть невозможным событием. Как известно, вероятность невозможного события, в каком-то смысле, сильнее нуля – ведь если рассуждать в классическом сеттинге, с действительными числами, то событие с нулевой вероятностью – может произойти. Например, если вы бросаете безразмерную точку на действительную окружность, то вероятность попасть в любое конкретное действительное число тождественно равна нулю, но в какое-то число вы всегда попадёте. Другое дело, что точно записать такие попадания – не выйдет, потому что нельзя записать точно большинство действительных чисел.
Одно и то же пустое множество можно помещать в разные коробки, получая разные пустые коробки. А пустая коробка может служить существенным признаком. Посмотрим на CAA-записи в DNS. Интерпретация этих записей отличается в случае, когда запись есть, но её значение – пустая строка, и в случае, когда нет самой CAA-записи. Здесь буквально проявляется эффект, позволяющий строить натуральные числа из пустого множества: когда нет CAA-записи – это настоящий нуль, пустое множество; когда CAA-запись есть, но она пустая – это уже единица, потому что возможна только одна пустая CAA-запись (ну или так: все пустые CAA-записи – одинаковые). То есть, тут, с одной стороны, играет роль определение того, чего нет: “нет значения CAA-записи” против “нет самой CAA-записи”; с другой стороны – содержательный эффект возникает из погружения пустого множества в большую структуру. Это, в точности, процесс (∅=0, {∅}=1).
Процесс погружения ∅ в {} даёт основной инструмент для генерирования множеств. Фигурные скобки обозначают операцию “множество из (элементов)” (set of). Так, {∅} – это множество из одного элемента, пустого множества. При этом одноэлементное множество (singleton, синглетон) – это не то же самое, что один этот элемент. То есть, заметьте, что {} и {∅} (или, если хотите, {{}}) – сильно разные вещи. Если, борясь за логическую стройность, ввести дополнительно понятие “класса”, как способа избежать возникновения абсурдного “множества всех множеств”, то пересечение всех классов – это и будет пустое множество. Именно поэтому в английском, например, языке пустое множество правильно обозначать как the empty set, с определённым артиклем the, а не an empty set. “A set”, но “the empty set”.
Данное важное свойство закреплено, – обычно!, – и в современных языках программирования высокого уровня. Если написать, что var a := {1} (то есть, переменная a – это массив из одной целой единицы по определению), то станет верным, что 1 != a (то есть, одна целая единица не равна массиву, состоящему из одной целой единицы).
А если взять JavaScript, то можно наблюдать сразу несколько особенностей интерпретации пустого множества и “ссылок” на пустое множество в программировании:
const set = new Set();
const object = {};
set.add(1);
set.add("two");
set.add(object);
set.add(object);
set.add({});
console.log(set.size);
for (const item of set.keys()) {
console.log(item);
}
– эта программа напечатает вот что:
4
1
two
Object { }
Object { }
– ничего странного, но довольно показательно.
Оставим JavaScript и его объекты. В шумерских способах записи чисел для обозначения отсутствия единиц использовали пробел. Занятно, что в шумерской системе, изначально, отличались обозначения для единиц, относящихся к разным типам объектов: предположим, обозначения для мер зерновых отличались от обозначений для мер воды. Это, конечно, связано с тем, что древнейшие системы просто фиксировали количество объектов при помощи изображений именно этих объектов, чтобы можно было попарно сопоставить изображение и реальность: видим три кувшина – рисуем три кувшина в качестве обозначения того, что кувшинов три; видим пять мехов с водой – рисуем пять мехов, в качестве обозначения, что мехов пять, и, возможно, знак воды рядом. Потому что тут ещё нет операции выноса типа выше числа: “кувшины” – три (палки); “меха” – пять (палок). И пустое множество демонстрирует свою уникальность: нет кувшинов, нет мехов – просто не обозначаем кувшины и меха. И именно поэтому пробел, как носитель “пустоты”, в шумерской схеме записи мог появиться только тогда, когда обозначения единиц для счёта уже отделились от типов объектов. То есть, введение пробела произошло сильно позже отказа от зарисовки “мехов и кувшинов”. Понятно, что отдельное обозначение для нуля требуется только в схеме “тип” – “количество”, где количество записывается абстрактно.
Пустое множество – аксиоматично. Так, чрезвычайно часто встречающийся в популярной литературе феномен, известный как “набор аксиом теории множеств” ZFC, буквально содержит аксиому о пустом множестве: “существует пустое множество”. Пустое тут – это то, в котором нет элементов, но оно – множество: то есть, множество, к которому не принадлежит ни один элемент. Получается, “пустота” множества может выступать как предикат: “[A] есть пустое”, и без пустого множества построение логических теорий становится затруднительным.
Удивительно, но побочный эффект того, что всякий элемент не принадлежит пустому множеству, вне зависисмости от типа, приводит к следующему обобщению: для элементов пустого множества всё что угодно – верно. Элементам пустого множества оказывается возможно приписать любое свойство. Это используется даже в модных “интернет-мемах”, как способ наведения сарказма:
никто: [%blah-blah-blah%] иванов: подпрыгивает на батуте
– тут совсем условные обозначения, конечно: “[%blah-blah-blah%]” – пустое, “батут” – содержание. Главное – схема: “никто: {}, кто-то: {предмет мема}”. “Когда никто не догадался, кроме Иванова”.
Комментарии (2) »
Как ещё можно понять, что не бывает квадратных корней из отрицательных чисел? Например, воспользовавшись отношением порядка. Таких корней из отрицательных чисел не бывает над действительными, потому что квадрат любого действительного числа – неотрицателен. Это свойство непосредственно связано с тем, что на действительных числах есть отношение порядка. Ведь что такое отрицательное число? Это число, которое меньше нуля, и при этом “меньше” обладает некоторыми дополнительными, глобальными свойствами (можно сравнить все числа, результат сохраняет арифметику и т.д.). В комплексных числах – такого нет.
То есть, из этого прямо следует, что и квадрат никакого комплексного числа не может быть меньше нуля! Но по другой причине: потому, что в комплексных числах как раз нет полноценного отношения порядка, аналогичного тому, которое есть для действительных. В комплексных числах нельзя сказать, что вот это число – “отрицательное”, меньше нуля, а вот это – “положительное”, больше нуля. Строго говоря, всякие способы “сравнения” комплексных чисел придумать возможно, – например, по значению модуля, по алфавиту записи, ещё как-то, – но никакой из этих способов не будет совместим с арифметической структурой комплексных чисел, соответственно, не будет задавать линейный порядок, сохраняющий операции, которые и делают комплексные числа – комплексными.
Если взять то самое знаменитое √(-121), из труда Бомбелли, то это не есть действительное число, ведь оно не является ни отрицательным, ни положительным, ни нулём. Почему ни отрицательным, ни положительным? По тому самому порядку, который описан выше: отрицательное – это меньше нуля; положительное – это когда нуль меньше числа. Почему не является нулём? Потому что иначе “схлопывается” вся арифметика: должно быть 2 + √(-121) = 2. Но раз нет подходящего отношения порядка, то нет и отрицательных/положительных. Это всё отмечено у Бомбелли – буквально, он пишет, что “такой радикал не может быть назван ни положительным, ни отрицательным”. В его “Алгебре” это означало, что у значения вида √(-121) есть особенная сигнатура, а поэтому нужно ввести дополнительную операцию по работе с этой сигнатурой, что в истории математики и принято называть изобретением “мнимой единицы”.
Посмотрим на ситуацию чуть более детально, пусть и не совсем строго. Положим, что обычные “плюсы” и “минусы” – это +1 и -1, а “необычные”, комплексные, это +i и -i. Мы получили кортеж значений: {+1, -1, +i, -i}. Попробуем ввести привычное отношение порядка, сохраняющее “естественную” арифметику. Предположим, что -i < 0 (отрицательное), а +i > 0 (положительное). Тогда (+i)*(+i) должно быть положительным, больше нуля.
Однако, согласно свойствами мнимой единицы, (+i)*(+i) = -1 – именно это и позволяет выносить сигнатуру из-под знака радикала: √(-121) = (+i)*11. Получается, что -1 > 0, то есть, -1 – положительное? Но тогда -i = (+i)*(-1) должно быть тоже положительным, ведь мы и приняли, что +i – положительное, и нашли, что -1 – тоже положительное. Следовательно, уже из соображений симметрии, +1 – отрицательное, то есть, +1 < 0. Странно, не так ли? Более того, +i – тоже отрицательное. Но мы ведь приняли, что +i – положительное? Противоречие. Поэтому-то ввести тут привычные отрицательные и положительные числа, но с сигнатурой i, не получится. Не получится и построить отношение линейного порядка “с арифметикой” на комплексных числах. Это ещё одно доказательство того, что никаких квадратных корней из отрицательных чисел быть не может – нарушится логика построения числовых структур.
Что же это за √(-121)? Что получается, если “возвести его в квадрат”? √(-121) – это комплексное число. Когда вы его возводите в квадрат, то тоже получаете комплексное число: -121 + i*0. То, что мнимая часть здесь “умножена на ноль”, вообще говоря, не делает число автоматически действительным. Потому что базовая операция умножения проводилась в комплексных, её результат – комплексное число, поэтому -121 = -121 + i*0 – комплексное. Тут всегда пары значений. А “забыть о комплексных” – это уже дополнительная операция, которая позволяет сопоставить некоторые комплексные числа – действительным (не парам действительных, заметьте!); операция, так сказать, позволяет спустить некоторые комплексные – в действительные. Да, эта операция регулярно подразумевается. Отсюда и надуманная “противоречивость”, из которой стало модно делать кричащие, но ложные, утверждения: мол, “можно” извлечь квадратный корень из отрицательного числа, но “вам об этом не говорят”. Напоминает историю со школьной задачей про ящики и апельсины.
Комментировать »
Новый