стр. 1
(общее количество: 5)

ОГЛАВЛЕНИЕ

След. стр. >>

Основы теории алгоритмов

Коротков М.А.
Степанов Е.О.

14 сентября 2003 г.
Оглавление

1 Основы теории алгоритмов . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 Тезис Черча. Регистровые машины . . . . . . . . . . . . . . . . . . . . . . 9
3 Некоторые алгоритмические массовые проблемы . . . . . . . . . . . . . . 14
3.1 Самоприменимые программы . . . . . . . . . . . . . . . . . . . . . 15
3.2 Проблема останова . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.3 Теорема Райса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4 Разрешимость и перечислимость множества тавтологий . . . . . . . . . . 20
5 Формальные теории . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
5.1 Теорема о неподвижной точке . . . . . . . . . . . . . . . . . . . . . 29
5.2 Теорема Тарского . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.3 Вторая теорема Геделя . . . . . . . . . . . . . . . . . . . . . . . . . 31
6 Язык Пролог . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
6.1 Формальная Система Опровержения . . . . . . . . . . . . . . . . 35
3


1 Основы теории алгоритмов
Ранее мы занимались изучением языков, предназначенных для описания рассуждений.
Теперь мы “поменяем угол зрения” и будем рассматривать языки, предназначенные
для записи конкретных действий. Языки логики предикатов относятся к классу де-
кларативных (описательных): смысл элемента такого языка (формулы) заключается
в описании чего-либо. Те же языки, к изучению которых мы приступаем, можно на-
звать языками инструкций, так как их элементы, называемые часто инструкциями,
являются предписаниями исполнителю (человеку, компьютеру, другому вычислитель-
ному устройству) совершить определенный набор действий. Поскольку набор точных
инструкций для выполнения конкретных действий принято называть алгоритмом или
программой, такие языки инструкций часто называются алгоритмическими языками
или языками программирования. Последние два термина часто употребляются в слегка
разных контекстах: под языком программирования обычно понимают язык инструк-
ций для реально существующего вычислительного устройства – компьютера (Fortran,
Basic, Pascal, C++ и т.п.), а термин алгоритмический язык употребляется в более
широком смысле и включает в себя как языки программирования, так и другие языки
инструкций, в частности псевдоязыки, предназначенные для описания алгоритмов.
Смещение нашего внимания с логических языков на языки инструкций обусловлено
желанием дать ответы на те вопросы, котроые остались открытыми в нашем иссле-
довании возможностей логических языков, а именно, на вопросы о том, каким обра-
зом проверять истинность различного рода семантических утверждений о формулах
языков логики предикатов (например, как проверить, является ли заданная формула
языка логики первого или второго порядка тавтологией). Мы уже отметили, что непо-
средственная проверка семантических свойств формул логических языков при помощи
определений практически никогда не представляется возможной, и поэтому специально
рассмотрели механизмы, предназначенные для конструктивной проверки семантиче-
ских свойств (формальные системы). Мы также доказали, что среди таких механизмов
есть “хорошие”, то есть одновременно корректные и полные, по крайней мере для язы-
ков логики первого порядка. Пользуясь такой формальной системой, можно заменить
проверку того, является ли данная формула тавтологией, на поиск вывода данной фор-
мулы при помощи формальной системы из пустого множества посылок (иначе говоря,
поиску доказательства данной формулы из пустого множества посылок). Однако, оста-
ется неясным, каким образом искать такой вывод. Можно ли, например, предъявить
конкретный алгоритм вывода любой тавтологии? Интересен и другой вопрос: можно
ли предъявить такой алгоритм, который по заданной формуле логического языка даст
однозначный ответ, выводима ли данная формула из пустого множества посылок, то
есть является ли тавтологией, или нет?
Мы пока подобного рода вопросами не интересовались. Кстати, на практике многие
люди и не интересуются ими. Например, математики ищут доказательства математи-
ческих утверждений, как правило не задумываясь о том, можно ли предъявить уни-
версальный алгоритм их поиска. Подобного рода вопросы можно, конечно, задавать не
4 Основы теории алгоритмов


только о логических языках. Например, игроков в шахматы, возможно, интересет во-
прос о том, может ли партия в шахматы всегда быть выиграна белыми (естественно, при
соблюдении правил игры). Ответ в данном случае положительный: описание алгоритма
решения этой задачи можно найти у Дональда Э. Кнута (“Искусство программирова-
ния”, том 1, стр 314). Правда, проблема в том, что для выполнения этого алгоритма
требуется невероятно большое время даже при использовании самых современных и
быстродействующих вычислительных устройств, причем нет никакой надежды, что в
обозримом будущем появятся компьютры, способные реализовать этот алгоритм за при-
емлемое время.
В этом разделе мы покажем, что использование языков инструкций помогает от-
ветить на ряд вопросов о логических языках, подобных только что рассмотренным. В
качестве побочного эффекта исследования мы сможем доказать и целый ряд нетри-
виальных и практически важных утверждений о языках инструкций, в частности, о
невозможности решения некоторых важных алгоритмических задач.
Привыкший к математической строгости изложения читатель наверняка уже об-
ратил внимание на то, что мы неоднократно и весьма вольно пользовались понятием
алгоритма, не давая его строго определения. Дело в том, что нам бы не хотелось по-
свящать слишком много времени формализации этого понятия. Во-первых, потому, что
читатель, как мы надеемся, обладает хотя бы элементарными основами алгоритмиче-
ской культуры, под которой понимается не обязательно умение писать программы для
компьютера, но хотя бы умение записать кулинарный рецепт так, чтобы его могла при-
менить любая домохозяйка: написание такого рецепта в математических терминах как
раз и есть составление алгоритма приготовления блюда. Во-вторы, вопросу о том, что
такое алгоритм посвящены многочисленные пухлые тома специальной литературы, чте-
ние которых, как показвывает практика, ни в коей мере не способствуют практической
работе с алгоритмами: так, чтобы грамотно записать рецепт приготовления котлет, не
нужно знать формального опредления алгоритма. Так что для наших целей достаточно
будет лишь общего понимания алгоритма, как эффективного описания некоторых дей-
ствий. Данный термин был впервые введен в 1936 году А. Черчем, который предложил
считать действие M эффективным (или эффективно описанным), если

• M описано конечным числом точных инструкций, каждая из которых выражена
конечных числом символов;

• в случае, когда M проводится правильно, оно обязательно дает желаемый резуль-
тат за конечное время (конечное число шагов);

• M может быть в принципе проведено человеком вооруженным “пером и бумагой”;

• проведение M не требует “ни проницательности ни изобретательности” от испол-
нителя. “Человек, вооруженный карандашом, бумагой и системой знаний о пред-
мете представляет собой пример эффективного вычислителя” (Тьюринг, 1948).
5


Под алгоритмом мы будем понимать эффективное описание действия, при этом поз-
воляя себе достаточно вольно обращаться с терминами алгоритм, программа, эффек-
тивное описание, употребляя их почти как синонимы. Единственное отличие, на кото-
рое стоит обратить внимание, состоит в том, что программа в нашем понимании может
выполняться “бесконечное” время (например, программа, печатающая в бесконечном
цикле одно и то же слово). Термин “бесконечное” не зря взят в кавычки, ведь бесконеч-
ное время является абстракцией, которую в реальной жизни никто не видел. Опять-
таки, любители математического формализма могут считать бесконечно выполняющу-
юся программу набором бесконечного числа конечных алгоритмов. Предоставляем же-
лающим возможность самим сформулировать соответствующие “строгое” определение,
если они видят в этом необходимость.
Примером алгоритма из школьной арифметики явлется алгоритм Евклида провер-
ки того, является ли заданное число простым. Рецепт из поваренной книги может тоже,
хотя и с некоторыми оговорками, рассматриваться как алгоритм. Рецепт всегда коне-
чен (иначе исполнитель умрет с голода), но вот инструкции в рецепте не всегда точны
(вряд ли кто-то станет утверждать, что предписания “возьмите небольшую кастрюлю”,
“добавьте сахар по вкусу” и подобные им могут считаться действительно точными), по-
этому и желаемый результат (вкусная пища) не всегда достигается. На самом деле для
достижения результата как раз требуется “изобретательность и проницательность” ис-
полнителя (в данном случае мастерство повара), что противоречит понятию эффектив-
ного действия. Тем не менее, если пренебречь некоторой неточностью, можно считать
рецепт примером алгоритма.
Нас будут в дальнейшем интересовать два типа алгоритмов: алгоритмы распознава-
ния и алгоритмы вычисления. Начнем с алгоритмов распознавания. Рассмотрим алфа-
вит A. Предположим, задано по некоторым правилам множество L ? A? . Нас интере-
сует следующий вопрос: можно ли предъявить такой алгоритм, который будет распо-
знавать элементы множества L? Иными словами, можно ли написать такую программу,
которая при подаче на вход слова из A? через конечное время (т.е. за конечное число
шагов) выдавала бы ответ, принадлежит ли данное слово множеству L или нет. Введем
следующее определение.

Определение 1.1 Множество L ? A? называется разрешимым, если существует
такой алгоритм (программа), при подаче на вход которого произвольного слова из
A? за конечное число шагов алгоритм завершается выдачей ответа, принадлежит
ли данное слово множеству L или нет. Соответствующий алгоритм (программа)
называется разрешающим (разрещающей) для данного множества.

Нас будет интересовать и другой вопрос: можно ли написать программу, которая
генерировала бы на выходе все элементы данного множества, и только элементы этого
множества (естественно, эта программа должна выполняться бесконечно, если множе-
ство L бесконечно). Введем соответствующее определение.
6 Основы теории алгоритмов


Определение 1.2 Множество L ? A? называется перечислимым, если существует
такая программа, которая выводит на выход все слова множества L, и только их,
то есть в результате работы программы на выходе рано или поздно появится каж-
дое слово из L, и никаких других слов не появится. Соответствующая программа
называется перечисляющей программой.
Подчеркнем, что перечисляющая программа может печатать элементы множества
L в любом порядке и с любым количеством повторений. Определение 1.2 формулирует
лишь два требования:
• любое слово из L рано или поздно будет выведено;
• никаких слов из A? \ L выведено не будет.
Прежде чем перейти к свойствам разрешимых и перечислимых множеств, приведем
некоторые простейшие примеры. Во-первых, если множество L состоит из конечного
числа элементов, то оно очевидно разрешимо и перечислимо. Вот чуть менее тривиаль-
ный пример.
Пример 1.1 Рассмотрим алфавит английского языка. Пусть L – это множество
палиндромов (слов, которые одинаково читаются в обе стороны) 1 .
Это множество перечислимо: мы можем написать программу, генерирующую по-
следовательно палиндром за палиндромом. Она никогда не остановится, но каждый
палиндром рано или поздно появиться на выходе программы. Приведем перечисляющую
программу (пример написан на псевдокоде, а не конкретом языке программирования)
alphabeth_letters = {set_of _english_letters}

f unction generate_next_palindrome(previous_palindrome, needed_length)
{
if (length(previous_palindrome) == needed_length)
print(previous_palindrome);
else f oreach (alphabeth_letters as letter)
generate_next_palindrome(letter + previous_palindrome + letter, needed_length);
}

start_length = 1;
while (T RU E) do
{
generate_next_palindrome( , start_length);
f oreach (alphabeth_letters as letter)
generate_next_palindrome(letter, start_length);
start_length + +;
}
1
Для любопытных: на http://www.palindromelist.com можно найти палиндром, длиной почти
25000 символов (правда, в данном палиндроме не учитываются пробелы и знаки препинания).
7


Это же множество к тому же и разрешимо, потому что можно написать про-
грамму, которая брала бы на вход любую строчку из A? и указывала бы, палиндром
это или нет, за конечное время. Предлагаем читателю написать такую программу
на любом доступном ему языке программирования.

Упражнение 1.1 Пусть алфавит A является множеством десятичных цифр (A :=
{0, 1, . . . , 9}). При этом множество A? будем отождествлять с множеством нату-
ральных чисел. Пусть L – множество тех слов из A? , которые соответствуют про-
стым числам. Является ли это множество разрешимиым? перечислимым?

Возникает вопрос, в каком соотношении находятся перечислимые множества и раз-
решимые множества. Ответ на него дает следующее предложение.

Предложение 1.1 Всякое разрешимое множество перечислимо.

Для доказательства нам потребуется определение лексикографического порядка в
?
A.

Определение 1.3 Порядок (A? , <) назыается лексикографическим, если p < q, когда
либо длина слова p ? A? меньше длины слова q ? A? , либо, при равной длине слов p и
q, слово p предшествует q в алфавитном порядке.

Теперь можно доказать предложение 1.1
Доказательство: Следующий алгоритм перечисляет элементы разрешимого множе-
ства L ? A? : в цикле генерируем в лексикографическом порядке строчки из A? (сначала
в алфавитном порядке слова длины 1, потом в алфавитном порядке слова длины 2 и
т.п.), и подаем каждое сгенерированное слово на вход разрешающей программе. Послед-
няя за конечное число шагов завершится, выдав ответ, либо о том, что данное слово
принадлежит L, либо, что оно не принадлежит L. В первом случае выдаем сгенери-
рованное слово на выход, во втором случае игнорируем его и переходим к генерации
следующего слова из A? .
Справедливы следующие простые утверждения.

Предложение 1.2 Если разрешимо множество L ? A? , то разрешимо, а значит и
перечислимо, его дополнение A? \ L.

Доказательство: Если поменять в разрешающем алгоритме для множества L вы-
дачу ответа “слово принадлежит L” на “слово не принадлежит A? \ L” и наоборот, то
получится разрешающий алгоритм для A? \ L.

Предложение 1.3 Множество L ? A? разрешимо, если и только если перечислимы
одновременно оно само и и его дополнение A? \ L.
8 Основы теории алгоритмов


Доказательство: Из предложений 1.1 и 1.2 следует, что разрешимость множества
L влечет перечислимость его самого и его дополнения A? \ L. Предположим теперь,
что L и A? \ L перечислимы, и докажем, что в этом случае L должно быть разреши-
мым. Разрешающий алгоритм для L следующий: после ввода слова из A? запускаются
параллельно перечисляющие программы для L и для A? \ L. Рано или поздно при-
нятое на вход слово появится на выходе либо первой либо второй программы в силу
определения перечислимости множества. В первом случае следует выдать ответ о при-
надлежности проверяемого слова множеству L, во втором – о непринадлежности, после
чего следует завершить работу программы. “Параллельность” запуска сразу двух пе-
речисляющих программ достигается чередованием передачи управления на каждую из
этих программ, скажем, через регулярные промежутки времени. Иначе говоря, сна-
чала запускается первая программа, через определенный интервал времени она при-
останавливается и управление передается второй программе, а затем через регулярные
интервалы времени эти программы “меняются местами” (работавшая программа при-
останавливается, а управление передается на ранее приостановленную программу).
Теперь мы можем дать ответ на гораздо менее тривиальный вопрос о том, суще-
ствуют ли множества, которые не являются не только разрешимыми, но даже и пере-
числимыми. Интуитиция возможно подсказывает, что таких множеств нет, ибо в повсе-
дневной жизни мы имеем дело либо с конечными множествами, либо с множествами,
построенными каким-либо эффективным способом. Однако в данном случае доверять
интуиции нельзя, в силу следующего утверждения.

Предложение 1.4 Существуют неперечислимые множества.

Доказательство: Рассмотрим произвольный конечный алфавит A. Очевидно, что
мощность множества перечислимых подмножеств A? не превышает мощности множе-
ства всех перечисляющих программ. Последние же имеют мощность не превышающую
мощность всех вообще программ, работающих над алфавитом A. Так как все такие
программы записываются в виде конечных текстов на некотором языке с конечным
алфавитом, то множество всех таких программ не более чем счетно. Следовательно,
не более чем счетно и множестов всех перечислимых подмножеств A? . С другой сторо-
ны, множество A? счетно, а значит, множество всех подмножеств A? более чем счетно.
Таким образом среди подмножеств A? найдутся и неперичислимые.
Нам понадобятся в дальнейшем также понятия вычислимых и полувычислимых
функций. Сформулируем соответствующее определение.

Определение 1.4 Пусть A – заданный алфавит. Функция f : Domf ? A? > A? на-
зывается вычислимой, если существует программа, которая, при подаче на вход сло-
ва a ? A? , за конечное время (за конечное число шагов) выдаст f (a), если a ? Domf ,
либо, в противном случае, заранее оговоренный признак того, что a ? Domf . Соот-
/
ветствуящая программа называется вычисляющей. Обычно приходится иметь дело
с функциями, не принимающими значение (пустое слово), так что в этом случае
9


разумно резервировать в качестве признака того, что a ? Domf . В дальнейшем
/
мы будем всегда считать, что имеем дело именно с такой ситуацией.
Фунция f : Domf ? A? > A? называется полувычислимой, если существует
программа, которая, при подаче на вход слова Domf , за конечное время (за конечное
число шагов) выдаст f (a). Соответствующая программа называется полувычисляю-
щей. Работа полувычисляющей программы при подаче на вход слова из A? \ Domf не
определена (в этом случае программа может даже работать бесконечно).

Очевидно, что всякая вычислимая функция является и полувычислимый, так всякая
вычисляющая программа является одновременно полувычисляющей. Также очевидно,
что полувычислимая всюду определенная функция является вычислимой. Более точ-
но связь между вычислимостью и полувычислимостью характеризуется следующим
утверждением.

Предложение 1.5 Функция f : Domf ? A? > A? , где A – заданный алфавит,
вычислима если и только если полувычислимы одновременно f и характеристическая
функция множества Domf (последняя определяется как функция, принимающая зна-
чение на A? \ Domf и любое наперед заданное непустое значение из A? на Domf ).

Доказательство: Если характеристическая функция множества Domf полувычис-
лима, то она и вычислима, так как она определена всюду на A? , при этом соответству-
ющая полувычисляющая программа является очевидно и вычисляющей. Если к тому
же f полувычислима, то вычисляющую программу для f можно построить следующим
образом: при подаче на вход слова a ? A? сначала запускается вычисляющая програм-
ма для характеристической функции множества Domf ; если последняя завершается
выдачей ответа о том, что a ? Domf , то запускается полувычисляющуая программа
для функции f , в противном случае выводится .
Теперь по аналогии с вопросом о существовании неперечислимых множеств можно
задаться вопросом о существовании функций не являющихся полувычислимыми (такие
функции принято называть абсолютно невычислимыми). Ответ на него дает следующее
утверждение.

Предложение 1.6 Существуют абсолютно невычислимые функции.

Доказательство: Полная аналогия с доказательством предложения 1.4. Упражняй-
тесь.


2 Тезис Черча. Регистровые машины
Читатель, приверженный формальной математической строгости изложения, наверня-
ка удивился, читая предыдущий параграф, поскольку последний весь состоял из не
вполне понятных слов, так что все приведенные там утвержедения на самом деле нельзя
10 Тезис Черча. Регистровые машины


считать не только доказанными, но даже, строго говоря, корректно сформулированны-
ми. Стоило бы описать инструкцию, алгоритм и исполнителя, причем так, чтобы опи-
сание соостветствовало нашему интуитивному пониманию. Есть множество различных
построений: машина Тьюринга, рекурсивные и частично рекурсивные функции Чер-
ча, алгорифмы Маркова, машина Поста, регистровая машина. При этом как бы вы ни
формализовали понятие алгоритма, набор алгоритмов вы полчите, в некотором смыс-
ле, “совпадающий” с алгоритмами для других вычислителей. Имеет мето следующий
опытный факт: все вычислительные устройства эквивалентны в смысле алгоритмов,
которые могут на них выполняться. Данное утверждение называют тезисом Черча.

Тезис 2.1 Если существует эффективный метод вычисления значений функции, то
они могут быть вычислены и с помощью машины Тьюринга (или другого эффектив-
ного вычислителя)

Впоследствии утверждение тезиса было расширено до следующего: “любое эффек-
тивно описанное действие реализуется вычислительной машиной”. Тезис Черча (иногда
его называют тезисом Черча-Тьюринга, поскольку похожее утверждение было сфор-
мулировано Тьюрингом примерно в то же время) – утверждение эмпирического, а не
математического характера, он связывает формализованные понятия (описание кон-
кретного вычислителя) с не формализованными понятиями алгоритма, эффективного
описания.
Если мы конкретизируем таким образом понятия алгоритма, программы, вычис-
лительного устойства, то мы получим уже формальные определения перечислимости
и разрешимости множеств. В зависимости от конкретизации будут получатся разные
определения.
Конкретизация, которую будем рассматривать мы, называятся регистровой маши-
ной. Исполнителем будет являтся иедальное вычислительное устройство – регистровая
машина. Для регистровых машин введем понятия: регистровая разрешимость, реги-
стровая перечислимость, регистровая вычислимость функций, регистровая полувычис-
лимость функций. Все эти определения получаются заменой понятия “алгоритм” на
“алгоритм для регистровых машин.”
Тезис Черча для нас будет выглядеть следующим образом: разрешимые и перечис-
лимые множества совпадают с разрешимыми и перечислимыми множествами в смысле
регистровых машин.

Определение 2.1 Регистровая машина определяется как набор элементов:

• Внешнего алфавита A, с которым она работает;

• Пустого символа ? A (напечатать пустой символ – это значит ничего не
напечатать, но задействовать при этом устройство печати);

• Набора регистров: R0 , . . . , Rm ;
11


• Набора операторов для описания алгоритмов для регистровой машины следую-
щего вида:

1. ? LET Ri = Ri + ai
2. ? LET Ri = Ri ? ai ;
3. ? IF Ri = T HEN ? ELSE ?0 OR ?1 OR . . . ?n ;
4. ? P RIN T
5. ? halt

Где ai ? A, ? – номер, метка.

Алфавит представляет собой слова: A = {a0 , a1 , . . . , an } Рассмотрим приведенные
операторы:

• ? LET Ri = Ri + ai
в содержимое регистра (ленты) Ri справа дописать букву ai ;

• ? LET Ri = Ri ? ai ;
если в регистре Ri слово заканчивается справа на букву ai , то эта буква стирается;

• ? IF Ri = T HEN ? ELSE?0 OR?1 OR ?2 . . . OR?n ;
условный переход: если Ri пусто, то тогда сделать переход на метку ? , в против-
ном случае, если Ri заканчивается на ai , то перейти на метку ?i (если заканчива-

стр. 1
(общее количество: 5)

ОГЛАВЛЕНИЕ

След. стр. >>