Мне очень интересно. Приведите пожалуйста такой пример.
Ок. Хоть и лень вбивать много букафф, но раз народ просит, то положение, как говорится, обязывает
Множество вычислимых функций, как было справедливо замечено выше, действительно алгоритмически не перечислимо. Зато алгоритмически перечислимо множество программ, вычисляющих одноместные функции. В принципе, об этом достаточно много сказано в любом учебнике по теории алгоритмов, так что поясню тезис довольно кратко. Если мы зафиксируем вычислительное устройство и язык программирования (например, машину Тьюринга со стандартной системой команд или обычный компьютер, снабжённый потенциально бесконечной памятью, и один из стандартных языков программирования, типа Паскаля или Си), то процедура проверки синтаксической правильности программы эффективна и существует алгоритм, проверяющий любой текст за конечное время и определяющий, является ли этот текст синтаксически правильно написанной программой. Так что мы можем, тупо перебирая все тексты (i.e. конечные последовательности символов заранее заданного конечного алфавита), выбирать из них все, являющиеся программами без синтаксических ошибок, и составлять из них список. Таким образом, мы можем эффективно сформировать список
всех программ , которые синтаксически корректны.
Далее. Из программ мы, на самом деле, можем выбирать только те, которые начинаются с оператора ввода некоторого числа, а заканчиваются оператором вывода некоторого числа, причём других операторов ввода и вывода в программе не присутствует. Таким образом, мы можем считать, что каждая программа в нашем списке предназначается для вычисления некоторой функции из
в
. Мы считаем, что наше вычислительное устройство обладает свойством
универсальности, то есть что для любой вычислимой функции из
в
найдётся число
, такое что программа
вычисляет эту функцию.
Но тут есть одна тонкость. Несмотря на то, что каждая вычислимая функция вычисляется некоторой программой из нашего списка, отнюдь не каждая программа из списка вычисляет всюду определённую вычислимую функцию из
в
. Дело в том, что программа, даже если она не содержит синтаксических ошибок, при некоторых входных данных может "зацикливаться", никогда не заканчивая работу. Стандартное соглашение, принимаемое в теории алгоритмов на этот счёт, гласит, что при тех входных данных, при которых программа "зацикливается", значение вычисляемой ею функции не определено. Таким образом, если не ограничиваться определёнными на всех натуральных аргументах функциями, а рассматривать наряду с ними также
частичные функции из
в
, то можно считать, что каждого
программа
вычисляет некоторую частичную функцию
.
Далее. Введём трёхместную частичную функцию
от трёх натуральных аргументов:
,
и
. Мы считаем, что
, если программа
, вычисляя значение
, выдала ответ
не более чем за
шагов работы вычислительного устройства. В противном случае мы считаем, что
не определено. Очевидно, что
Кроме того, очевидно, что введённая трёхместная функция вычислима в самом сильном смысле. То есть по данной тройке натуральных чисел
мы за конечное число шагов можем сказать, определено ли значение
, и если оно определено, то можем сказать, чему оно равно.
Теперь мы хотим задать действительное число
. Мы опишем некоторую эффективную процедуру (i.e. алгоритм), который будет перечислять последовательность десятичных разрядов
. Процедура будет работать по шагам. На каждом шаге мы будем перечислять один или более элементов этой последовательности в порядке возрастания их индексов. Имея такую процедуру, мы можем утверждать, что функция, сопоставляющая натуральному числу
разряд
, вычислима. Действительно, чтобы для данного
вычислить, чему равно
, нам надо, получив на вход это
, запустить указанную процедуру и дождаться, когда она перечислит
-ый член последовательности. Это произойдёт за конечное время.
Переходим к описанию шагов процедуры. На каждом шаге все натуральные числа будут делиться на активные и пассивные. Перед началом работы все натуральные числа считаются активными. На каждом шаге от силы одно число будет переходить из разряда активных в разряд пассивных. Числа, ставшие пассивными, в дальнейшем уже не смогут становиться активными. Опишем действия, производимые процедурой на шаге
для произвольного натурального
.
Шаг . Смотрим, существует ли активное число
, такое что
определено. Если нет, то перечисляем в последовательность гамма-итых число
и переходим к следующему шагу. Если существует, то пусть
--- наименьшее среди таких чисел. Так как
определено, то мы знаем натуральное число
, такое что
. Сделаем число
пассивным. Затем если
, то опять перечисляем в последовательность число
и переходим к следующему шагу. Если же
, то перечислим в последовательность сначала
, затем
нулей и перейдём к следующему шагу.
Описание процедуры закончено. Докажем несколько лемм, из которых будет следовать, что для числа
функция
не вычислима.
Лемма 1. Если значение
определено, то на некотором шаге число
становится пассивным.
Доказательство. Индукция по
. Пусть для всех
это так. Пусть
настолько велико, что все числа
, для которых
определено, стали пассивными до шага
. Пусть теперь
таково, что
,
и
определено. Если число
ещё не стало пассивным до шага
, то оно станет таковым на шаге
.
Лемма 2. В последовательности
встречается ровно
идущих подряд нулей тогда и только тогда, когда на некотором шаге
число
становится пассивным и
.
Доказательство. Напрямую следует из описания конструкции.
Лемма 3. Для построенного числа функция
не вычислима.
Доказательство. Пусть
вычислима. Тогда
для некоторого натурального
и всех натуральных
. Так как
определена на всех натуральных аргументах, то значение
определено. По лемме 1 число
станет пассивным на некотором шаге. По лемме 2 в последовательности десятичных разрядов нашего числа встретится ровно
идущих подряд нулей тогда и только тогда, когда
. Противоречие с определением функции
.
Ну вот, сопственна, и фсё