Найти в Дзене
Одиночная палата

История программирования. Глава 2. Связь времен

Иллюстрация из "Книги перемен" ("И цзин")
Иллюстрация из "Книги перемен" ("И цзин")

В сердце любого современного полупроводникового микропроцессора стоит так называемое арифметико-логическое устройство (АЛУ)[1]. Из предыдущей главы становится понятно, что Аналитическая машина Бэббиджа не в полной мере представляла из себя современный компьютер. В ней отсутствовал элемент логики. Так и первая программа для этой машины, описанная Адой Лавлейс, не вполне может считаться программой в современном понимании этого термина. Да, алгоритм вычисления чисел Бернулли всё еще является алгоритмом, но он не содержит одного важного элемента - условного перехода. Фактически Лавлейс описала метод представления рекурсивной формулы в виде цикла со стековой памятью. Логическая операция ветвления, которая здесь присутствует в виде условия: "Если еще не достигнут нужный элемент последовательности, то вернуться к началу", на самом деле отдается на волю оператора машины.

Тут необходимо немного отойти в сторону и привнести другие входящие к контексту основного повествования. Вообще говоря, основными элементами АЛУ, являются еще более элементарные устройства - сумматоры. Основой которых, в свою очередь, являются транзисторы, сделанные из тех самых полупроводников. Объяснение того как работают полупроводники и как из них собираются транзисторы в рамках цикла об истории программирования, наверное, будет избыточным, но тем кому не очень понятен принцип предлагаю самостоятельно ознакомиться в Википедии. Сумматоры по сути выполняют операции сложения двоичных чисел, так же как это бы делала Аналитическая машина или любой более примитивный механический арифмометр. Другое дело, что если в механических устройствах происходило непосредственное сложение двух чисел, то в современном сумматоре операция сложения хитрым образом заменена на логическую схему. То есть если машина Бэббиджа это скорее АУ, без Л, то современное АЛУ, просто ЛУ, без А.

Логика оперирует только двумя значениями: "истина" и "ложь". Однако ничего не мешает нам представить любое целое число в двоичном исчислении. А в двоичном исчислении мы так же оперируем всего двумя значениями: нулем и единицей. Оставалось лишь придумать каким образом заменить операцию сложения единиц и нулей логическими операциями над "истиной" и "ложью". И, что на первый взгляд не удивительно, придумали. А за одно стало возможно управлять вычислительным процессом и строить алгоритмы не только с помощью арифметических операций, циклов и регистров памяти, но и с применением непосредственно логических высказываний. Так между собой связаны программы, как абстрактные алгоритмические конструкции, с вычислительными устройствами.

Однако за кажущейся простотой этих выкладок стоит долгий и тернистый путь проделанный людьми от древне-египетской иероглифики и китайской философии, через работы Готфрида Лейбница и Джорджа Буля, до основополагающей работы Клода Шеннона "Символический анализ релейных и переключательных схем", опубликованной в 1963 году.

Обратите внимание, что речь в работе Шеннона идет не о полупроводниках, а об электрических реле - первых примитивных электрических переключателях. Которые, к слову, уже были доступны во время работы Беббиджа над Аналитической машиной в середине XIX века. И что бы глубже понимать современное программирование нужно иметь представление и о цепочке событий, приведших сперва к отделению программ от вычислительных устройств, затем обратно к слиянию понятия алгоритма и некоего физического устройства, и потом еще раз к той абстракции, которую программисты имеют нынче.

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

Так, рассуждение о возникновении первых настоящих программ относит нас далеко в прошлое - во времена, когда только зарождалась письменность. Надо полагать, что считать в уме люди умели и задолго до появления письменных источников. Когда у человека появилась абстракция в виде натурального числа установить вряд ли возможно. Есть мнение, что считать умеют даже многие животные[3]. Однако, последние вряд ли имеют при этом ввиду какие-то системы счисления. А вот счет как система действительно был связан с письменностью. Людям как-то надо было записывать числа. И если количество отдельных слов, обозначающих разные феномены относительно невелико. До такой степени, что, в принципе, можно было каждое слово обозначить одним или несколькими отдельными символами - иероглифами. То, понятно, для всех чисел свой иероглиф придумать было невозможно. Появились первые системы символов, для записи чисел - позиционные системы счисления.

Парадоксально, но систем счисления изначально было великое множество. Чуть ли не каждый древний язык имел свою систему. Причем далеко не всегда десятичную, к которой человечество пришло вовсе не интуитивно, как можно было бы подумать, а в результате многочисленных проб и ошибок. Тот факт, что у человека на руках десять пальцев, каким-то образом не сразу и не для для всех стал очевидным выбором в пользу десяти позиций. Так, например, существуют свидетельства, что в Древнем Китае в ходу в какой-то период использовалась и двоичная система[4].

Для записи чисел в одном из сохранившихся древних китайских манускриптов использовались т.н. "триграммы" - иероглифы в виде чередования трех сплошных (1) и прерывистых линий (0). То есть как бы выразились сегодня - количество информации кодируемой этими символами соответствовало двойке возведенной в куб - 8 битам. Далее эти триграммы устанавливались друг над другом, обозначая старший разряд и превращаясь в гексаграммы, кодирующие уже 64 бит информации. И так далее.

Впрочем, свидетельств того, что в Древнем Китае такая система широко использовалась для арифметических вычислений нет. Как нет и свидетельств того, что и в других похожих системах люди смогли перенести её на следующий уровень - на уровень математической логики. Вплоть до 1666 года, когда Лейбниц опубликовал свою работу "Искусство комбинаторики" (De arte combinatoria). И вдохнул таким образом новую жизнь в двоичную систему исчисления, окончательно связав логику с арифметикой. Причем, несмотря на огромную временную дистанцию, Лейбниц, очевидно, непосредственно черпал вдохновение из древнекитайских манускриптов. В переводе заглавие одной из его книг звучит дословно так: "Объяснение двоичной арифметики, в которой используются только символы 1 и 0, с некоторыми замечаниями о ее полезности и освещении древних китайских фигур Фу Си"[5].

Еще почти два века понадобилось, что бы связать воедино математическую логику и арифметику Лейбница с алгеброй. Когда предикатами стало возможно пользоваться в точности как и прочими математическими объектами, и записывать действия над ними виде выражений, уравнений, а также, собственно, алгоритмов вычислений. Это удалось совершить Джорджу Булю в 1854 году, буквально несколько лет спустя после того, как Бэббидж оставил все попытки сконструировать свой "компьютер".

Есть некая злая ирония в этой истории. Казалось бы, эпоха бурного роста науки, инженерного дела, экономики наконец позволила человечеству реализовать на практике "Святой Грааль" тогдашней вычислительной техники, но вот чуть-чуть не срослось. Буль немного "запоздал" со своей алгеброй, Генри, не подоспел с электромагнитным реле, да и ставка в те годы делалась на более популярную в то время механистическую инженерию, на модной паровой тяге. И здесь, как будто, возникает некий ничем необоснованный пробел в развитии вычислительной техники. Будто был упущен какой-то переломный момент, до повторения которого пришлось ждать еще сто лет.

Однако, если чуть глубже разобраться в причинах и следствиях последующих, после провала Бэббиджа, событий в истории вычислительных устройств, а вместе с ними и программ, то становится понятно, что и этот период был весьма насыщен событиями. Мог ли компьютер в современном виде появиться раньше? Что было для этого нужно, сколько еще звезд должны были дополнительно сойтись в одну точку на небосклоне? Почему надо было сперва опять объединить программы и устройства, что бы уже окончательно развести их в две независимые сущности? Или может быть не окончательно? Об этом предлагаю поговорить в следующей главе.

1. Александр В. М. Арифметико-логическое устройство (АЛУ). // Цифровая и аналоговая техника в радиосвязи. URL : https://digteh.ru/proc/ALU/ (дата обращения: 10.07.22)

2. J. J. O'Connor, E. F. Robertson. Babylonian numerals. URL: https://mathshistory.st-andrews.ac.uk/HistTopics/Babylonian_numerals/ (дата обращения: 10.07.22)

3. J. Cepelewicz. Animals Count and Use Zero. How Far Does Their Number Sense Go? // Quanta magazine. URL : https://www.quantamagazine.org/animals-can-count-and-use-zero-how-far-does-their-number-sense-go-20210809/

4. A. Holloway. Creation of binary code inspired by 5,000-year-old text. URL : https://www.ancient-origins.net/news-general/creation-binary-code-inspired-5000-year-old-text-001468

5. G. Leibnitz. Explication de l’arithmétique binaire, qui se sert des seuls caractères O et I avec des remarques sur son utilité et sur ce qu’elle donne le sens des anciennes figures chinoises de Fohy. URL : https://hal.archives-ouvertes.fr/ads-00104781/document

Запощено под James Horner - A Beautiful Mind (OST)