Примечание G [a] — это компьютерный алгоритм , написанный Адой Лавлейс , который был разработан для вычисления чисел Бернулли с использованием гипотетической аналитической машины . Примечание G, как правило, считается первым алгоритмом, специально предназначенным для компьютера, [1] [2] [3] [4] и в результате Лавлейс считается первым программистом . [5] [6] [7] [8] Алгоритм был последним в серии, обозначенной буквами от A до G, которые она использовала в качестве наглядных пособий для сопровождения своего английского перевода французской транскрипции Луиджи Менабреа 1842 года лекции Чарльза Бэббиджа об аналитической машине в Туринском университете , «Notions sur la machine analytique de Charles Babbage» («Элементы аналитической машины Чарльза Бэббиджа»). [7] [9] Примечание G Лавлейс никогда не тестировалось, поскольку машина так и не была построена. Ее заметки вместе с ее переводом были опубликованы в 1843 году. [6] [7]
В современную эпоху , благодаря более доступному вычислительному оборудованию и программным ресурсам, алгоритм Лавлейс был протестирован, после того как был «переведен» на современные языки программирования. Эти тесты независимо друг от друга пришли к выводу, что в скрипте была ошибка из-за незначительной типографской ошибки, делающей алгоритм в его первоначальном состоянии непригодным для использования. [10] [11]
В 1840 году Чарльз Бэббидж был приглашен провести семинар в Турине , посвященный его аналитической машине [12], единственное публичное объяснение, которое он когда-либо давал о машине. [13] Во время лекции Бэббиджа математик Луиджи Менабреа написал отчет о машине на французском языке. [12] Друг Бэббиджа, Чарльз Уитстон , предложил Лавлейс перевести отчет Менабреа, чтобы внести свой вклад. [12] [14] Бэббидж предложил ей дополнить отчет приложениями, которые она составила в конце своего перевода в виде серии из семи «заметок», помеченных как AG. Ее перевод был опубликован в августе 1843 года [12] в «Научных мемуарах » Тейлора [14] [15] , где имя Лавлейс было подписано «AAL». [12] [b] В этих заметках Лавлейс описал возможности аналитической машины Бэббиджа, если бы ее можно было использовать для вычислений, изложив более амбициозный план для машины, чем даже у самого Бэббиджа. [3] [15] [16]
Заметки Лавлейс к статье были в три раза длиннее самой статьи. [17] В первых заметках она выходит за рамки числовых амбиций, которые Бэббидж питал к машине, и предполагает, что машина могла бы воспользоваться вычислительными возможностями для работы в областях музыки, графики [18] и языка. [8] [19] [20]
Опять же, он мог бы действовать на другие вещи, помимо числа, если бы были найдены объекты, чьи взаимные фундаментальные отношения могли бы быть выражены с помощью абстрактной науки операций, и которые также должны были бы поддаваться адаптации к действию операционной нотации и механизма машины. Предположив, например, что фундаментальные отношения тональных звуков в науке гармонии и музыкальной композиции поддавались бы такому выражению и адаптации, машина могла бы сочинять сложные и научные музыкальные произведения любой степени сложности или объема.
— Ада Лавлейс, Заметки о мемуарах «Набросок аналитической машины, изобретенной Чарльзом Бэббиджем» переводчицы Ады Августы, графини Лавлейс, Примечание А
Она объясняет читателям, как аналитическая машина была отделена от более ранней разностной машины Бэббиджа , [21] и сравнивает ее функцию с машиной Жаккарда , [22] в том, что она использовала двоичные перфокарты для обозначения машинного языка . В примечании C эта точка зрения подкрепляется тем фактом, что машина может выполнять одновременные и итеративные действия, гарантируя, что любая карта или набор карт могут использоваться несколько раз при решении одной задачи, [20] по сути предвосхищая современные методы потока управления и циклирования. [17] [23] Эти идеи были доведены до кульминации в заключительном примечании G, где Лавлейс стремилась продемонстрировать пример вычисления .
Примечание G использовало только четыре арифметические операции : сложение, вычитание, умножение и деление, реализацию видения Бэббиджа:
Ввиду невозможности здесь объяснить процесс, посредством которого достигается эта цель, мы должны ограничиться признанием того, что первые четыре операции арифметики, то есть сложение, вычитание, умножение и деление, могут быть выполнены непосредственно посредством вмешательства машины. При условии этого машина способна выполнять все виды числовых вычислений, поскольку все такие вычисления в конечном итоге сводятся к четырем операциям, которые мы только что назвали.
— Чарльз Бэббидж, «Эскиз аналитической машины, изобретенной Чарльзом Бэббиджем»
Он также использует идею Бэббиджа о хранении информации в столбцах дисков, каждый из которых обозначается символом (для переменной ) и нижним индексом, указывающим, к какому столбцу относится ссылка.
Лавлейс использовала рекурсивное уравнение для вычисления чисел Бернулли, [12] в котором она использовала предыдущие значения в уравнении для генерации следующего. Ее метод работал следующим образом: [24]
где - биномиальный коэффициент ,
Числа Бернулли можно вычислить многими способами , но Лавлейс намеренно выбрала сложный метод, чтобы продемонстрировать мощь машины. В примечании G она заявляет: «Мы закончим эти заметки, подробно проследив шаги, с помощью которых машина могла вычислять Числа Бернулли, что является (в той форме, в которой мы выведем это) довольно сложным примером ее возможностей». [20] Конкретный алгоритм, используемый Лавлейс в примечании G, генерирует восьмое число Бернулли (обозначенное как , поскольку она начала с .) [24]
Таблица алгоритма организует каждую команду по порядку. Каждая команда обозначает одну операцию , выполняемую над двумя терминами. Во втором столбце указывается только используемый оператор. Переменные обозначаются как " ", [c] , где верхний индекс перед ним представляет количество различных значений, которым была назначена переменная, а нижний индекс после него представляет порядковое назначение переменной, то есть какая это переменная. (Например, относится ко второму назначению переменной номер 4. Любые переменные, которые до сих пор не определены, имеют верхний индекс 0.) Переменные нумеруются, начиная с . Третий столбец сообщает компьютеру, какая именно команда выполняется (Например, в строке 1 выполняемая команда - " " - первая итерация переменной 2 умножается на первую итерацию переменной 3.) и включает только одну операцию между двумя терминами в строке. Столбец 4 - "Переменные, получающие результаты" отмечает, где должен храниться результат операции в столбце 3. Таким образом, все переменные в этом столбце имеют верхний индекс, увеличивающийся на единицу каждый раз. (например, в строке 1 результат присваивается переменным , , и .)
В столбце 5 указано, была ли изменена какая-либо из переменных, используемых в работе команды. Заключенные в фигурные скобки, две строки на команду помещают исходную переменную слева от знака равенства, а новую переменную с другой стороны — то есть, если переменная была изменена, ее верхний индекс увеличивается на единицу, а если нет, он остается прежним. (например, строка три присваивает результат второй итерации переменной , а пятый столбец отражает это, отмечая;
изменилось, но не изменилось.
В столбце 6, «Заявление о результатах», результат, назначенный переменной в столбце 4, показан в его точном значении, основанном на значениях двух ранее назначенных терминов. (например, в строке 1 - - было установлено в начале как , и было установлено как переменная . Следовательно, , в математической нотации .) Этот столбец, по-видимому, не вычисляется движком и, по-видимому, больше предназначен для ясности и способности читателя следить за шагами программы. (Например, в строке 5 дробь делится на два, что обозначено как умножение на половину, вероятно, для связности и типографской сложности вложенной дроби.) Он также использует отдельные переменные обозначения вне программы, переменные и , которые последовательно умножаются для нахождения конечного значения, , таким образом: [10]
Помимо этого, каждый последующий столбец показывает значения данной переменной с течением времени. Каждый раз, когда переменная изменяется или ее значение становится релевантным по признаку ее присутствия в качестве одного из терминов в текущей команде, ее значение указывается или переопределяется в соответствующем столбце. В противном случае оно помечается многоточием, чтобы обозначить его нерелевантность. Это, по-видимому, имитирует потребность компьютера только в релевантной информации, тем самым отслеживая значение переменной по мере того, как программа анализирует . [10]
Программа стремилась вычислить то, что по современным правилам известно как восьмое число Бернулли, обозначенное как , поскольку Лавлейс начинает отсчет с . [24]
В операции 4 деление, предположительно имеющее место, это " ", которое должно быть сохранено в переменной . Однако в "Сообщении о результатах" говорится, что деление должно быть:
На самом деле, деление выполнено наоборот; является второй итерацией , как видно из операции 2. Аналогично, является второй итерацией , как видно из операции 3. Таким образом, операция 4 должна быть не , а . Эта ошибка означает, что если бы движок когда-либо запустил этот алгоритм в этом состоянии, он не смог бы правильно сгенерировать числа Бернулли и обнаружил бы, что его конечное целевое значение ( восьмое число Бернулли, ) равно .
Программа Лавлейс может быть реализована на современном языке программирования , хотя из-за указанной выше ошибки, если ее точно переписать, она вернет неверное конечное значение для . Исходная программа, обобщенная в псевдокоде, выглядит следующим образом:
В[1] = 1В[2] = 2V[3] = n (n = 4 в программе Лавлейс.)V[4] = V[4] - V[1]V[5] = V[5] + V[1]V[11] = V[5] / V[4]V[11] = V[11] / V[2]V[13] = V[13] - V[11]V[10] = V[3] - V[1]V[7] = V[2] + V[7]V[11] = V[6] / V[7]V[12] = V[21] * V[11]V[13] = V[12] + V[13]V[10] = V[10] - V[1]V[6] = V[6] - V[1]V[7]= V[1] + V[7]//Завершить позже
Реализация в псевдокоде подчеркивает тот факт, что компьютерные языки определяют переменные в стеке , что устраняет необходимость отслеживания и указания текущей итерации переменной. Кроме того, программа Лавлейс допускала определение переменных только путем выполнения сложения , вычитания , умножения или деления двух членов, которые ранее были определенными переменными. Современный синтаксис мог бы выполнять каждое вычисление более кратко. Это ограничение становится очевидным в нескольких местах, например, в команде 6 ( ). Здесь Лавлейс определяет до сих пор неопределенную переменную ( ) сама по себе, тем самым предполагая, что все неопределенные переменные автоматически равны 0, тогда как большинство современных языков программирования вернули бы ошибку или перечислили бы переменную как null . Она имела в виду " ", но ограничила себя использованием только переменных в качестве членов. Аналогично, в команде 8 ( ) строгая запись двухчленной арифметики становится громоздкой, так как для того, чтобы определить как 2, Лавлейс присваивает его значение (0) себе плюс (2). Именно из-за этой ограничительной нотации и дается такое определение.