<< Пред. стр.

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

ОГЛАВЛЕНИЕ

След. стр. >>

ется на a1 – перейти на ?1 , на a2 – перейти на ?2 , и т.д.)

• ? P RIN T
напечатать содержимое регистра R0 (R0 – регистр ввода-вывода);

• ? halt
оператор завершения программы.

К оператору IF необходим некоторый комментарий: так как регистровые машины
являются теоритическим построением, то мы вправе требовать, чтобы в операторе были
перечислены все слова алфавита (их конечное число).

Определение 2.2 Программой для регистровой машины или регистровой програм-
мой будем называть конечный набор инструкций-операторов, определенных выше. Каж-
дая инструкция ?i имеет метку i, то есть они нумеруются последовательно. Во всех
инструкциях вида

?i IF Ri = T HEN ? ELSE ?0 OR ?1 OR . . . ?n

метки,
?1 , ? 2 , . . . , ? n
12 Тезис Черча. Регистровые машины


не превосходят метки ?k (последней метки в программе). Иными словами, переход
осуществляется только на реально существующие метки. Кроме того, инструкция
?k имеет такой вид:
?k = k halt,

и инструкции halt более в программе не встречается.


Идеальность вычислителя заключается в следующем:

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

• во-вторых, мы не ставим ограничений на длину программы (если бы регистровая
машина была реализована на компьютере с 256Mb оперативной памяти, то про-
грамма максимальной длины, работающая над алфавитом ASCII, занимала бы
“всего” порядка 15000 машинописных страниц, то есть 435000 километров текста)


Определение 2.3 Будем говорить, что регистровая программа P , при подаче слова
? ? A? на вход, рано или поздно останавливается (? ? A? > halt), если программа P
начинается со слова ? в регистре R0 и пустого слова во всех остальных регистрах.
Далее выполняются последовательно все инструкции программы в соответствии с
вышеизложенными правилами, и рано или поздно происходит остановка. В против-
ном случае будем говорить, что программа P при подаче на вход слова ? зациклива-
ется.


Определение 2.4 Будем говорить, что программа P при подаче на вход слова ? вы-
дает на выходе слово ? ? A? , если после запуска программы рано или поздно произой-
дет остановка, и кроме того к моменту остановки на выходном устройстве будет
напечатано слово ? и никаких других слов.


Напечатать пустое слово – значит не напечатать ничего, но задействовать при этом
выходное устройство. Предположим, что, например, на выходном устройстве есть еще
лампочка, показывающая, было оно задействовано или нет.


Пример 2.1 Алфавит A такой: A = { , |}. В этом алфавите интерпретируем
как число 0, | как число 1, || – 2, . . . и так и далее. Написать программу, которая
бы определяла, какое на входе число, четное или нечетное. Если число нечетное, то
она бы печатала (останавливалась бы, ничего не печатая), в противном случае
печатала бы |.
13


Приведем простой вариант этой программы.

1 LET R0 = R0 ? |
2 IF R0 = T HEN 5 ELSE 3
3 LET R0 = R0 ? |
4 IF R0 = T HEN 7 ELSE 1
5 P RIN T R0
6 IF R0 = T HEN 9 ELSE 9
7 LET R0 = R0 + |
8 P RIN T R0
9 halt

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

1 LET R0 = R0 ? |
2 IF R0 = T HEN 6 ELSE 3
3 LET R0 = R0 ? |
4 IF R0 = T HEN 5 ELSE 1
5 LET R0 = R0 + |
6 P RIN T R0
7 halt

Теперь можно дать окончательные определения разрешимых и перечислимых мно-
жеств.

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

Упражнение 2.1 Алфавит A такой: A = {a, b}. Напишите разрешающую и пере-
числяющую регистровые программы для множества палиндромов.

Приведенная конструкция (регистровая машина) конечно не предсталяет собой удоб-
ное для программирования устройство, но, в силу тезиса Черча, является эквивалентом
любого другого устройства. А так как достаточно формализованные вычислительные
устройства удобнее при теоритических построениях, то мы будем рассматривать именно
ее.
14 Некоторые алгоритмические массовые проблемы


3 Некоторые алгоритмические массовые проблемы
Когда мы сформулировали, что такое алгоритм, мы можем получит несколько кон-
структивных результатов. Первый вопрос, который мы поставим, это вопрос о том,
можно ли разрешить множество всех самоприменимых регистровых программ, ина-
че говоря, существует ли алгоритм, определяющий корректно ли поданная на вход
программа работает с собственным кодом? И второй вопрос: а можно ли разрешить
множество всех программ корректно работающих с заданными начальными данными
(например, пустым словом)?
Данные вопросы представляют собой приметы массовых проблем, а именно, мы
поставили цель найти алгоритм рашающий данныю задачу для всех программ.
Возьмем программу вычисляющую значение некоторой функции. Правильность про-
граммы обычно проверяется путем тестирования, то есть проверки программы на ко-
нечном (пусть и большом) множестве входных данных. Множество же всех возмож-
ных входных данных может оказаться бесконечным. Анализ кода дает принципиально
иной результат – мы можем гарантировать, что, при соблюдении некоторых условий,
программа вычислит верное значение функции, а не сообщать, что программа проте-
стирована на 2 (5, 100, 1000) тестах. Возникает вопрос: а всегда ли осуществима та-
кая проверка? Такие проверки хотелось бы проводить с помощью другой программы–
верификатора. Вопрос же заключается в следующем: а существует ли такой верифика-
тор (и если да, то как его построить, и имеет ли смысл его применять).
На самом деле, такой проверяющий алгоритм построить нельзя, отчасти по причине
его универсальности. Однако это не означает невозможность решения более узкой зада-
чи. В таком случае говорят: массовая проблема такого рода неразрешима. То есть, хотя
и не существует общего алгоритма проверки программы, но для некоторых (довольно
узких) классов программ его можно построить.
Программа является достаточно неудобным объектом для операций над ней, зна-
чительно проще оперировать с числами, поэтому сейчас мы установим соответствие
между числами и программами. Внешний алфавит программы A, A = {|}, множество
слов над ним A? ; (здесь мы неявно подразумеваем также наличие пустого символа,
то есть, A = { , |}). Расширим этот алфавит в соответствии с языком, на котором пи-
шутся программы: B := A ? {a . . . z, 0 . . . 1, =, ?, +, , ;} ( здесь не “пустой символ”,
а “символ, обозначающий пустой символ”), B алфавит регистровых программ; тогда
B ? множество слов над алфавитом B.

Определение 3.1 Эффективная нумерация программ Геделя ставит в соответствие
каждой регистровой программе натуральное число (называемое номером Геделя про-
граммы) по следующему правилу: слова из множества B ? перебираются в лексикогра-
фическом порядке; в случае, если данное слово является программой, ему присваива-
ется порядковый номер.

Замечание 3.1 То, что очередное слово является программой, устанавливается с по-
мощью синтаксического анализатора (грубо говоря, слово является программой, если
3.1 Самоприменимые программы 15


отсутствуют ошибки компиляции). В нашем случае можно взять слово, и пооче-
редно сравнивать его со всеми словами (генерируемыми программой, которая счита-
ет номера Геделя) как только слова совпадут, так сразу мы и найдем номер Геделя
нашей программы. Причем так как слова мы генерируем по росту их длины, то мы
также сможем узнать что слово не является программой. Таким образом у нас есть
конструктивный алгоритм, устанавливающий соответствие между номерами про-
грамм (числами Геделя) и самими программами.

Номера Геделя программ определим следующим образом: элементу a0 ? A? со-
? ?
? ?
поставим номер n := a0 , . . . , a0 . Теперь можно формализовать заявленное ранее
? ?
n раз
действие “подадим некому алгоритму на вход текст программы”. Алгоритм будет полу-
чать элементы множества A? , то есть, соответствующее число Геделя (в то время как
сам текст программы принадлежит B ? ).

Лемма 3.1 Множество {? : ? = ?P , P программа над A? } разрешимо.


3.1 Самоприменимые программы
Теперь перейдем к вопросу о проверке того, принадлежит ли программа некоторому
классу.

Определение 3.2 Множество самоприменимых программ – ?halt := {?p : P : ?p > halt}
– множество программ, корректно работающих с собственным кодом, то есть, кото-
рые когда-либо остановятся, имея свой текст (свое число Геделя) в качестве входных
данных.

Вопрос 1 Является ли множество ?halt разрешимым?

Теорема 3.1 Множество ?halt программ корректно работающих с собственным ко-
дом неразрешимо.

Доказательство: Предположим обратное, то есть, пусть существует разрешающая
его программа
?P > , ?P ? ?halt (P : ?P > halt),
P0 :
?P > ? = , ?P ? ?halt (P : ?P > ?);
/
которая ничего не выдает на печать в случае, если поданное ей на вход число Геделя
соответствует программе, корректно работающей со своим кодом, и наоборот, выводит
на печать непустое слово в противном случае.
16 Некоторые алгоритмические массовые проблемы


Модифицируем эту программу P0 . Ее исходный текст выглядит следующим образом:

0. . . . ;
··· ···
?. PRINT;
··· ···
k. halt;

Вставим на k-ую строку оператор “k. IF R0 = THEN k ELSE k+1 OR k+1 OR . . . OR k+
1;” сдвинув вниз “(k+1). halt;” и заменим все строки вида “?. PRINT;” на “?. GOTO k;”,
где “GOTO k” осуществляет безусловный переход на k-ый оператор, то есть является со-
кращенной записью для инструкции “IF R0 = THEN k ELSE k OR k OR . . . OR k”.
Назовем полученную программу P1 .
Программа P1 ведет себя следующим образом: получая на вход число Геделя некой
программы из ?halt , программа успешно доходит до строки k, где зацикливается (дей-
ствительно, программа P0 в этом случае ничего не выводила на печать, следовательно,
инструкции вывода на печать не задействовались). В случае же, если входные данные
соответствуют программе, не входящей в ?halt , мы достигнем строки k с непустым ну-
левым регистром (R0 ) и будет совершен переход на к оператору k + 1, то есть, успешное
завершение P1 .
При такой схеме поведения программы мы получим противоречие, подав ей на вход
ее собственное число Геделя. Действительно, подадим ей на вход собственное число
Геделя, если оно из ?halt , то программа зациклится, а значит не является программой
корректно работающей с собственным кодом. А если программа не является корректно
работающей с собственным кодом, то и ее номер не принадлежит ?halt . Мы пришли к
противоречию, следовательно, разрешающего алгоритма не существует. .
Отрицательный ответ на поставленный вопрос означает неразрешимость массовой
проблемы, что не значит, что для некоторого, быть может, очень узкого класса програм
нельзя построить проверяющий алгоритм.

3.2 Проблема останова
Рассмотрим следующую проблему. Положим, что у нас есть программа, которая “яко-
бы вычисляет” значения функции y = x2 , и мы хотим это проверить. Проблема со-
ответствия программ поставленным задачам – проблема верификации. Но мы можем
упростить задачу, остановившись на проблеме более простого характера. Например, за-
вершит ли программа работу при подаче на вход числа 2. И, даже, ещё упростить –
завершится ли программа при подаче ей на вход пустого слова.

Определение 3.3 ?halt := {?p : P : > halt} – множество программ (номеров Геде-
ля), которые когда-нибудь остановятся (при пустых входных данных);

Вопрос 2 Является ли множество ?halt разрешимым?
3.2 Проблема останова 17


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

Теорема 3.2 Множество ?halt программ корректно работающих с пустым входным
словом неразрешимо.

Доказательство: Предположим существование аналогичной программы P0 для на-
шего случая:
?P > , ?P ? ?halt (P : > halt),
P0 :
?P > ? = , ?P ? ?halt (P :
/ > ?);
Теперь объясним как с ее помощью получить разрешающую программу для ?halt :
мы хотим проверить, корректно ли программа ?1 работает с собственным номером Ге-
деля. Рассмотрим программу ?2 , полученную из ?1 сдвигом всех операторов исходной
программы на n? (ее номер Геделя) вниз, записав на освободившиеся n? строк:

0. LET R0 = R0 + a0 ;
1. LET R0 = R0 + a0 ;
2. LET R0 = R0 + a0 ;
...;
(n? ? 1). LET R0 = R0 + a0 ;

Кроме того преобразуем все операторы ? IF Ri = T HEN ? ELSE ?0 в (? +
n? ) IF Ri = T HEN (? + n? ) ELSE (?0 + n? ) Эта программа, получив на вход пу-
стое слово будет содержать номер Геделя программы ?1 в регистре R0 , и далее будет
следовать код программы ?1 (точнее, эквивалентный ему). В силу нашего предположе-
ния, множество ?halt разрешимо, то есть мы можем сказать остановится программа
?2 или нет. Но эта программа остановится при подаче ей на вход пустого слова если и
только если, программа ?1 остановится при работе с собственным номером Геделя. Та-
ким образом, мы пришли к тому, что множество ?halt – разрешимо, что противоречит
предыдущей теореме.
И отрицательный ответ, как и в предыдущем случае, означает неразрешимость мас-
совой проблемы. Верификация же отдельных программ является достаточно сложной,
но паринципиально разрешимой задачей. В критических задачах (например управле-
ния ядерным реактором или космическим спутником) где цена ошибки высока, можно
провести теоретическое доказательство соответствия поставленым условиям, что и яв-
ляется верификацией программы.

Упражнение 3.1 Доказать: ?halt и ?halt – перечислимые множества.

Указание: Поскольку перечислимость множества означает существование програм-
мы, которая при некоторых входных данных будет выдавать только элементы дан-
ного множества, причем рано или поздно выдаст их все, можно переформулировать
18 Некоторые алгоритмические массовые проблемы


условие данного упражнения: “предъявить перечисляющий алгоритм для данных мно-
жеств”.
Общая идея построения алгоритмов как для ?halt так и для ?halt такова: сначала
программы нужно модифицировать (вместо печати программа должна переходить
к следующей инструкции, а вместо инструкции halt выводить свой номер Геделя)
после этого запускаем программы параллельно, на каждой итерации выполняем по
одной инструкции из всех, и первую инструкцию программы с номером Геделя равным
номеру шага.


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

Теорема 3.3 Райса Пусть C – некое множество полувычислимых функций, причем
C = ? и C = {множество полувычислимых функций }, тогда множество номеров
Геделя программ, соответствующим этим функциям не является разрешимым.

Доказательство: Занумеруем все все программы, соответствующие полувычисли-
мым функциям. Получим некую номерацию Геделя. Пусть M – множество номеров
Геделя полувычислимых функций из C:

M := {x : fx ? C}

Теперь рассмотрим характеристическую функцию:

1, ? M (fx ? C)
1M (x) :=
0, x ? M (fx ? C)
/ /

Эта характеристическая функция “говорит”, является ли программа с данным номе-
ром полувычисляющей для одной из функций данного множества. Теперь рссмотрим
некоторую эффективную полувычислимую функцию f0 : dom(f0 ) = ?. И возьмем про-
извольную fa ? C. Рассмотрим такую функцию:

fa , x ? dom(fx (y)),
F (x, y) :=
f0 , в противном случае

Теперь фиксируем соответственно x. Получаем здесь функцию от y: F (x, y). У этой
функции от y будет некоторый номер Геделя. Этот номер Геделя мы обозначим g (x).
Для каждого фиксированного x он будет разный.
3.3 Теорема Райса 19


Ясно, что g (x) как функция от x будет полувычислимой. Теперь рассматриваем
fg(x) (y), то есть функцию, номер которой g (x). В силу определения функции F будем
иметь:
fa (y) , x ? dom(fx ),
fg(x) (y) =
f0 (y) , x ? dom(fx )
/


Таким образом, fg(x) ? C, если и только если fx (x) определена.
Рассмотрим теперь такую функцию:

1, x ? dom(fx ),
?m (g (x)) =
0, x ? dom(fx )
/

Получается, что если предполагаем, что множество M разрешимо, то множество
{x}, таких, что fx (x) определена, является разрешимым. То есть тем самым оказывает-
ся разрешимой и задаяа самоприменимости для регистровых машин. Что противоречит
теореме о неразрешимости задачи самоприменимости для регистровых машин. Следо-
вательно никакое нетривиальное множество полувычислимых функций разрешимым не
является.
Теорему Райса иногда формулируют так: никакое нетривиальное свойство (подмно-
жество) множества полувычислимых функций не является разрешимым.

Определение 3.4 Пусть Q некоторое свойство полувычислимых функций. Свойство
Q назовем нетривиальным, если существуют как функции, обладающие свойством Q,
так и функции не обладающие этим свойством.

Все обычно рассматриваемые свойства являются нетривиальными. Примерами нетри-
виальных свойств служат следующие:

• функция тождественно равна нулю;

• функция нигде не определена;

• функция всюду определена;

• функция взаимно однозначна;

• функция определена при x = 0.

Из теоремы Райса следует несколько утверждений о программах, вычисляющих
значния функций. Под функцией fx , мы будем понимать функцию, которая соответ-
ствует вычисляющей (полувычисляющей) программе с номером Геделя x.

Предложение 3.1
20 Разрешимость и перечислимость множества тавтологий


• нельзя с помощью универсального алгоритма проверить всюду ли определена
функция fx ;

• не существует алгоритма проверки того, будет ли программа вычислять нуле-
вую функцию;

• вопрос о том, вычисляют ли две программы одну и ту же функцию, массово
неразрешим;

<< Пред. стр.

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

ОГЛАВЛЕНИЕ

След. стр. >>