- •Введение
- •Глава 1
- •§ 1. «Алгоритмические джунгли»
- •§ 2. Исходные данные и результаты. Массовость алгоритма
- •§ 4. Понятность алгоритма
- •§ 5. Рекурсивные определения
- •§ 6. Определенность алгоритма
- •§ 7. Выводы
- •Глава 2 создание алгоритмов
- •§ 1. Роль алгоритмов в науке и технике
- •§ 2. Как возникают алгоритмы
- •§ 3. Алгоритмы в математике
- •§ 4. Алгоритм Евклида
- •§ 5. Решето Эрагосфена
- •§ 6. Алгоритм разложения на простые множители. Определение наименьшего кратного двух чисел
- •§ 7. Распознавание алгебраического тождества
- •§ 8. Задачи на построение алгоритмов
- •Глава 3 кризис математики в начале XX века
- •§ 1. Арифметизация математики
- •§ 2. Теория множеств
- •§ 3. Кардинальные числа
- •§ 4. Антиномии
- •§ 5. Выводы из антиномий
- •Глава 4 логические теории алгоритмов
- •§ 1. Рекурсивные функции
- •§ 2. Машины Тьюринга
- •§ 3. Нормальные алгоритмы Маркова
- •§ 4. Эквивалентность описанных теорий
- •Глава 5
- •§ 1. Массовые проблемы. Неразрешимость проблем
- •§ 2. Экстраалгоритм и три неразрешимые проблемы
- •§ 3, Некоторые замечания
- •Глава 6 электронные вычислительные машины и программирование
- •§ 1. Устройство эвм
- •§ 2. Процессоры эвм. Рабочий цикл
- •§ 3. Что такое программа
- •§ 4. Особенности современных эвм
- •§ 5. Входные языки программирования
- •§ 6. Необходимость содержательной теории алгоритмов. Какой она должна быть
- •Г л а в а 7 формальные языки
- •§ 1. Анализ естественного языка
- •§ 2. Искусственные языки. Формальные языки
- •§ 3. Буквы, связи, оболочки, конструкции
- •§ 4. Формальные грамматики
- •§ 5. Нотация Бекуса. Тезаурусы
- •§ 1. Что такое операция?
- •§ 2. Натуральные операции
- •§ 4. Первичные алгоритмы
- •§ 5. Натуральные алгоритмы
- •§ 6. Ограничения на структуру исходных данных сняты
- •§ 8. Соотношение с алгоритмами в интуитивном смысле
- •§ 10. Исследование тупиков (клинчей)
- •§ 11. Формальная семантика формального языка
- •Глава 9 математическое обеспечение эвм
- •§ 1. Анализ эвм и программ
- •§ 2. Что такое математическое обеспечение эвм
- •§ 3. Функциональная классификация программ математического обеспечения эвм
- •§ 4. Операционные системы
- •И автоматизация процессов
- •§ I. Использование эвм для управления
- •§ 2. Информационные системы
- •§ 3. Алгоритмизация процессов
- •§ 4. Язык алгоритмизации процессов
- •§ 5. Наука и искусство алгоритмизации
- •Заключение
- •§ 1. Может ли машина мыслить? Может ли человек решить алгоритмически неразрешимую проблему?
- •§ 2. Детерминированность машин. Самообучение
- •§ 3. Сознание машин. Алгоритмическое моделирование
§ 3. Что такое программа
Прежде всего заметим, что алгоритм работы процессора и программа его работы — это разные вещи. Некоторые процессоры (например центральные) при решении каждой задачи имеют свою программу, и алгоритм их работы является алгоритмом выполнения программ. В зависимости от их содержания (вида и взаимосвязи команд) такие процессоры могут перерабатывать информацию, находящуюся в ЗУ по-разному. Другие процессоры имеют свой алгоритм работы, но этот алгоритм работы не является алгоритмом выполнения программ. Примером является описанный в § 2 процессор ввода. Таковы же обычно и пульт управления и процессор выдачи.
В некоторых ЭВМ сложной конструкции процессоры ввода могут быть программными. Что же такое программа? Когда она присутствует и когда ее нет? Эти вопросы тонкие и ответить на них не так-то просто. Все же попытаемся это сделать. Прежде всего расскажем о том, как возникают программы. Особенности программ зависят от особенностей ЭВМ, которая их должна выполнять. Поэтому разъясняя, что такое программа, мы будем ее иллюстрировать программами для случая описанной выше структуры программного процессора.
Программы сперва составляют на бумаге и, естественно, что в таком виде они существенно отличаются от программ, находящихся в ЗУ процессора. Итак, сперва будем говорить о программах, написанных на бумаге.
Условимся, что адресами ячеек оперативной памяти являются натуральные числа. Для определенности положим, что каждый' адрес записывается в виде четырехзначного числа. Код операции будем записывать в виде двузначного числа.
Тогда командой назовем строку, содержащую код операции и три адреса19, разделенные пробелами. При этом условимся в каждой команде эти элементы располагать так: сперва код операции, потом первый, второй и третий адреса.
Примерами команд могут служить:
01 2425 3274 6153
34 2601 0000 0001
Смысл команд можно описать в виде таблицы, которую обычно называют системой команд. В таких таблицах мы сохраним правила записи формул, о которых условились в § 2. Допустим, что для нашего процессора система команд задана табл. 4.
В табл. 4 команда с кодом 13 фактически означает: от процессора ввода с перфокарт через буферную память получить п чисел. Аналогично команда с кодом 11 означает: ввести в буферную память процессора печати п чисел и заслать соответствующую информацию в его контактные ячейки. Команда с кодом 12 требует выполнения лишь первой части того, что требует команда «13»; ввода п чисел с перфокарт в буферную память. Их можно перенести в собственную память программного процессора оттуда по команде «14». Операции «12» и «13» и соответствующие виды команд введены для того, чтобы в тех случаях, когда это допускает решаемая задача, программный процессор, затребовав числа с перфокарт, не ожидал конца работы процессора ввода, а продолжал выполнение программы.
Последние четыре вида команд предусматривают контакт (с другими процессорами) и обмен информацией (с ними). Процесс выполнения таких команд будет разъяснен несколько позже (в §4).
Приказом будем называть строку, составленную из адреса, скобки и команды, записанных в том порядке, в котором они перечислены. Например, приказом является
3361) 02 0001 0003 0235
Вид команды |
Код операции |
Описание действий, предписываемых командой |
|||
01 |
i |
j |
k |
01 |
вычислить zi+zj и записать в zk |
02 |
i |
j |
k |
02 |
вычислить zi-zj и записать в zk |
03 |
i |
j |
k |
03 |
вычислить zi*zj и записать в zk |
04 |
i |
j |
k |
04 |
вычислить zi:zj и записать в zk |
05 |
i |
0000 |
k |
05 |
вычислить
|
06 |
i |
0000 |
k |
06 |
число zi записать в ячейке zk |
07 |
i |
j |
0000 |
07 |
условный переход к команде zi, если ω=0, и к команде zi, если ω=1 |
08 |
0000 |
j |
0000 |
08 |
переход к команде zj |
09 |
0000 |
0000 |
0000 |
09 |
останов процессора: запись числа 0 в ячейку t |
11 |
i |
n |
0000 |
11 |
n чисел zi, zi+1, …, zi+n-1 выдать на печать |
12 |
0000 |
n |
0000 |
12 |
n чисел ввести в буферную память с перфокарт |
13 |
0000 |
n |
k |
13 |
n чисел ввести с перфокарт и записать их в ячейки zk, zk+1, …, zk+n-1 |
14 |
0000 |
n |
k |
14 |
n чисел из буферной памяти перенести в ячейки zk, zk+1, …, zk+n-1 |
Θ |
i |
j |
k |
15≤θ≤99 и θ=10 или θ=00 |
останов процессора: запись числа 0 в ячейку t |
Адрес, стоящий в начале приказа, будем называть собственным адресом приказа.
Любой столбец приказов, если хотя бы один из них имеет собственный адрес 0001, будем называть программой, написанной на бумаге.
Хотя это и не имеет теоретического значения, всегда будем приказы размещать в порядке возрастания их собственных адресов. Как читатель сейчас поймет, практическое значение это имеет.
Программа, написанная на бумаге, будет превращена в программу, записанную в машине (в процессоре), если каждую команду поместить в ячейку оперативной памяти, адрес (номер) которой одинаков с собственным адресом приказа. Приведем пример составления программы.
Предположим, что нужно составить программу решения произвольного квадратного уравнения
ax2+bx+c=0 (а≠0),
если заданы числа а, b, с. Формула решения этого уравнения имеет вид
.
Корни
уравнения могут оказаться действительными
или комплексными. В первом случае будем
печатать каждый из них; во втором случае
это неудобно, так как
.
Тогда, очевидно, достаточно напечатать
только α и β. Но как, глядя на два
напечатанных числа, узнать, являются
ли они числами х1
и
х2
или
числами α
и
β? Для того чтобы можно было это узнать,
условимся предпосылать им третье число,
которое должно быть равно 2, если корни
действительные, и 4, если они комплексные.
Алгоритм решения нашей задачи можно записать в следующем виде.
1. Ввести в машину числа20 а, b, с, z=2, y=0 и перейти к п. 2.
2. Вычислить величины 2а, b2—4ас, —b. Обозначить их соответственно е, d, g и перейти к п. 3.
3. Если d≥0, перейти к п. 4, иначе перейти к п. 5.
4.
Вычислить
,
и
обозначить их соответственно x1
и
х2.
Перейти
к п. 6.
5.
Вычислить числа g:e,
,
обозначить
их21
соответственно x1
и
х2.
Умножить
z
само
на себя и результат (он равен 4)
обозначить через z.
Перейти
к п. 6.
6. Печатать числа z, х1, х2. Конец.
Составляя приведенный алгоритм, мы уже заранее учитывали порядок действий в программе, чего, может быть, читатель еще не умеет. Программу, соответствующую этому алгоритму, можно написать так: 0001) 123 0000 0005 0101
Этот приказ значит: ввести 5 чисел и записать их в ячейки оперативной памяти с номерами 101, 102, 103, 104, 105. Первые три число — это a, b, c, а последние — это z=2, y=0.
Выполняя приказы
0002) 03 0102 0102 0110
0003) 03 0101 0104 0111
0004) 03 0104 0111 0112
0005) 03 0112 0103 0112
0006) 02 0105 0102 0110
0007) 02 0110 0112 0112
последовательно получим
в ячейке №0110 число b2;
в ячейке №0111 число 2а;
в ячейке №0112 число 4a;
в ячейке №0112 число 4ac;
в ячейке №0110 число — b;
в ячейке №0112 число d=b2—4ас.
Эта группа приказов соответствует п. 2 алгоритма.
При выполнении последнего приказа в ячейке со окажется нуль, если d≥0, и единица, если d<0. Поэтому п. 3 алгоритма решения квадратного уравнения будет реализован, если мы составим приказ условного перехода:
0008) 07 0009 0050 0000
Во втором адресе последней команды мы написали 0050, потому что уверены, что ячеек, которые нам потребуются для записи приказов, соответствующих случаю d1230, немного, и ячейка 0050 не будет занята. Далее составим приказы
0009) 05 0112 0000 0112
0010) 02 0110 0112 0113
0011) 01 0110 0112 0114
0012) 04 0013 0111 0201
0013) 04 0114 0111 0202
0014) 06 0104 0000 0200
Эта группа приказов соответствует п. 4 алгоритма решения квадратного уравнения. В соответствии с ними последовательно будет получено
в
ячейке № 0112 число
;
в
ячейке № 0113 число
;
в
ячейке № 0114 число
;
в ячейке № 0201 число x1;
в ячейке № 0202 число х2;
в ячейке № 0200 число 2.
0015) 11 0200 0003 0000
0016) 09 0000 0000 0000
В силу этих приказов числа 2, Xi и х2 будут напечатаны. Затем процессор будет остановлен.
Теперь составим приказы, которые выполнялись бы в случае d<0, т. е. соответствующие п. 5 алгоритма решения квадратного уравнения. Первый из этих приказов имеет собственный адрес 0050.
Выполняя приказы
0050) 04 0110 0111 0201
0051) 02 0105 0112 0112
0052) 05 0112 0000 0112
0053) 04 0112 0111 0202
0054) 03 0104 0104 0200
0055) 08 0000 0015 0000
будем последовательно иметь
в ячейке № 0201 число (—b):(2а);
в ячейке № 0112 число —d;
в
ячейке № 0112 число
;
в
ячейке № 0202 число
;
в ячейке № 0200 число 4.
Наконец, последний приказ означает безусловный переход к приказу, имеющему собственный адрес 0015. На этом программа закончена.
Итак, мы ознакомились с составлением программы. Программисты разработали целый ряд приемов, позволяющих облегчить эту очень тяжелую, но и очень важную работу. О некоторых методах мы будем говорить ниже, хотя методика программирования и не составляет предмета данной книги.
Как уже было сказано, для решения задачи программа должна быть введена в машину. При этом в ячейки должны быть записаны только команды (а не полные приказы); собственные адреса, содержащиеся в приказах, указывают, в какие ячейки должны быть помещены команды, входящие в состав этих приказов. Ячейки запоминающего устройства представляют собой приборы, устойчиво сохраняющие свое состояние и меняющие его только в момент записи в них нового кода. Каждое состояние соответствует некоторому содержимому ячейки. Состояния, соответствующего ее пустоте, нет. Так устроены ЭВМ (почему так — это вопрос технический; в этой книге ответ на него не может быть дан). Кроме того, исходные данные и результаты тоже фиксируются в ячейках и физически могут иметь ту же форму, что и команды.
Ни один инженер и ни один математик, анализируя совокупность состояний ячеек программного процессора, не может сказать, содержится ли в них программа или нет, или, если хотите, всегда может сказать, что какая-то программа там есть. Конечно, если ему заранее не известно, что в ЭВМ введена такая-то программа.
Иногда приходится слышать афоризм: «Машина без программы — ничто. Машина с программой — все!» Очевидно, этот афоризм неверен. Действительно, чем отличается машина без программы от машины с программой? Только состоянием некоторых своих элементов (именно тех, из которых сделаны запоминающие устройства). Образно говоря, различие между машиной в первом и во втором случае такое же, как между винтовкой, заряженной и поставленной на предохранитель, и той же винтовкой, заряженной и взведенной. Функционирование винтовки, поставленной на предохранитель и взведенной при нажиме на спусковой крючок будет различным, хотя физически винтовка в обоих случаях одна и та же.
Какова бы ни была программа, введенная в ячейки собственного ЗУ программного процессора, он, будучи приведенным в действие, выполняет только свой алгоритм, пример которого приведен в § 2. Таково же поведение и всех других процессоров. Каждый из них выполняет свой алгоритм. Но алгоритм программного процессора подобран так, что с точки зрения пользователя, составившего по определенным правилам программу, процессор расчленяет свои исходные данные на «программу в машине» и ее исходные данные и выполняет эту программу. Это значит, что алгоритм процессора — алгоритм выполнения программы. Алгоритмы других процессоров имеют вспомогательное значение.
Если трактовать программы на бумаге и программы в машине как предложения некоторых языков, то наличие алгоритма их выполнения приводит к мысли, что программы в обеих формах являются алгоритмами. Но, конечно, не в смысле классических теорий, а пока что в интуитивном смысле.
