
- •Министерство образования и науки Российской Федерации
- •Цель лекции
- •План лекции
- •1 Происхождение вычислительных машин
- •2 Изучение алгоритмов
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Биты и их хранение
- •2 Оперативная память
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Устройства внешней памяти
- •3 Хранение и поиск файлов
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Представление числовых значений
- •2 Хранение целых чисел
- •3 Хранение дробей
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Представление текста
- •2 Представление изображений
- •Достоинства пиксельной графики
- •Недостатки пиксельной графики
- •Достоинства векторной графики
- •Недостатки векторной графики
- •3 Представление звука
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Сжатие изображений
- •2 Ошибки передачи данных
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Архитектура эвм
- •2 Связь процессора с другими устройствами
- •3 Другие архитектуры
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Машинный язык
- •2 Пример машинного языка
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Выполнение программы
- •2 Пример выполнения программы
- •3 Программы и данные
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Логические операции
- •2 Операции сдвига
- •3 Арифметические операции
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Эволюция операционных систем
- •2 Архитектура операционных систем
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Понятие процесса
- •2 Управление процессами
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Классификация сетей
- •2 Сетевые протоколы*
- •3 Безопасность сетей
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Понятие алгоритма
- •2 Представление алгоритма
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Теория решения задач
- •2 Общие методы решения задач
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Алгоритм последовательного поиска
- •2 Управление циклами
- •3 Алгоритм сортировки методом вставки
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Алгоритмы поиска и сортировки
- •2 Управление рекурсией
- •3 Разработка рекурсивных процедур
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Эффективность алгоритмов
- •2 Верификация программ
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Эволюция и классификация языков программирования
- •2 Концепции традиционного программирования
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Процедурные единицы
- •2 Реализация языка программирования
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Объектно-ориентированное программирование
- •2 Декларативное программирование
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Структуры данных
- •Integer Scores (2.9).
- •2 Статические и динамические структуры
- •3 Указатели
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Массивы
- •2 Списки
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Структура и функции стека
- •2 Реализация стека
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Очереди
- •2 Деревья
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Пользовательские типы данных
- •Int Age;
- •2 Классы
- •Int *StackEntries;
- •3 Стандартная библиотека шаблонов
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Роль операционной системы
- •2 Последовательные файлы
- •3 Вопросы программирования
- •0000000010000110
- •001100010011001100110100
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Основные положения индексации
- •2 Вопросы программирования
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Основные положения хеширования
- •2 Вопросы программирования
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Общие вопросы
- •2 Система управления базой данных
- •3 Поддержка целостности баз данных
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Модели баз данных
- •2 Реляционная модель баз данных
- •3 Объектно-ориентированные базы данных
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Интеллект и машины
- •2 Распознавание образов
- •3 Мышление
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Искусственные нейронные сети
- •2 Генетические алгоритмы
- •Контрольные вопросы
- •Невычислимые функции Цель лекции
- •План лекции
- •1 Основы машины Тьюринга
- •2 Невычислимая функция
- •3 Сложность задач
- •Листинг 1. Процедура MergeLists для объединения двух упорядоченных списков
- •Листинг 2. Алгоритм сортировки слиянием, реализованный в процедуре MergeSort
- •Контрольные вопросы
- •Цель лекции
- •План лекции
- •1 Шифрование с открытым ключом
- •2 Модульная арифметика
- •Контрольные вопросы
- •Литература
- •Internet-ресурсы
2 Невычислимая функция
Теперь мы рассмотрим функцию, невычислимую по Тьюрингу, которая, согласно тезису Черча-Тьюринга, считается невычислимой в общем смысле. То есть вычисление этой функции лежит за пределами возможностей современных компьютеров.
Проблема останова. Невычислимая функция, с которой мы собираемся познакомиться, относится к проблеме, известной как проблема останова, которая (в неформальном смысле) сводится к предсказанию, остановится ли программа, если она была запущена с определенными начальными условиями. Например, рассмотрим простую программу на скелетном языке:
while X not 0 do:
incr X;
end;
Если мы запустим эту программу с начальным значением переменной X, равным нулю, цикл выполняться не будет, и программа вскоре завершится. Если же начальное значение X будет отличаться от нуля, цикл будет выполняться бесконечно, и процесс окажется непрерывным.
В этом случае легко сделать вывод, что выполнение программы прекратится только в случае, если запущена она была со значением X, равным 0. Однако если мы рассмотрим более сложные программы, задача предсказания их поведения существенно усложнится. В некоторых случаях, как мы увидим далее, решить эту задачу просто невозможно. Но сначала необходимо формализовать нашу терминологию и точнее сформулировать цели.
Предыдущий пример показал, что результат, то есть остановится ли в конечном итоге программа, может зависеть от начальных значений переменных. Поэтому, если мы хотим предсказать, прекратится ли выполнение программы, необходимо соблюдать аккуратность в отношении ее начальных значений. Выбор, который мы собираемся сделать в отношении этих значений, может показаться вам на первый взгляд странным, но не теряйте веры. Наша Цель лекции — воспользоваться преимуществами метода под названием самовызов, идея которого заключается в том, что объект обращается к самому себе. Эта уловка часто приводит к удивительным результатам в математике, начиная от таких курьезов, как утверждение «Это утверждение является ложным» до более серьезного парадокса, представленного вопросом «Содержит ли набор всех наборов само себя?». Мы собираемся подготовить ситуацию для последовательности умозаключений, схожей с «Если это есть, то этого нет; но если этого нет, то оно есть».
В нашем случае самовызов будет реализован путем назначения переменным программы значения, представляющего саму программу. Вспомните, что каждую программу на скелетном языке можно при помощи ASCII закодировать в виде одного длинного шаблона битов в формате «один символ на байт». Кроме того, каждая переменная в программе на скелетном языке принадлежит к типу «битовый шаблон произвольной длины», поэтому мы можем считать эту закодированную версию программы значением любой ее переменной.
Рассмотрим, что произойдет, если выполнить самовызов для простой программы
while X not 0 do;
incr X;
end;
Мы хотим узнать, что произойдет, если запустить эту программу, присвоив переменной X закодированный вариант самой программы (рис. 11.3). В этом случае ответ очевиден. Так как значение X не равно нулю, программа попадет в цикл и никогда не остановится. С другой стороны, если выполнить подобный эксперимент над программой
clear X;
while X not 0 do;
incr X;
end;
то она остановится, так как независимо от начального значения на момент достижения структуры while-end значением переменной X будет ноль.
Выведем следующее определение: программа на скелетном языке является самозавершающейся (selfterminating), если ее выполнение со значениями всех переменных, инициализированных закодированным представлением самой программы, приводит к окончанию выполнения. Проще говоря, программа является самозавершающейся, если ее выполнение прекращается при условии, что при запуске ей на вход была дана она сама. Это тот самый пример самовызова, о котором мы говорили.
Рисунок 2 – Тестирование программы на самозавершение
Обратите внимание, что свойство самозавершаемости программы обычно не имеет ничего общего с Цель лекциию написания этой программы. Это просто свойство, которым обладает или не обладает каждая программа на скелетном языке. То есть каждая программа на скелетном языке либо самозавершающаяся, либо нет.
Теперь мы можем точно описать проблему останова — это задача определения, является или не является программа на скелетном языке самозавершающейся. Скоро мы узнаем, что алгоритма для ответа на этот вопрос в общем случае не существует. То есть нет единственного алгоритма, который для любой программы на скелетном языке может определить, самозавершающаяся она или нет. По этой причине решение проблемы останова выходит за пределы возможностей компьютеров.
Тот факт, что мы явно решили проблему останова в предыдущих примерах и теперь утверждаем, что проблема останова неразрешима, может показаться противоречивым, поэтому сделаем небольшую остановку и разберемся подробнее. Наблюдения, сделанные нами в примерах, являлись уникальными для этих конкретных случаев, и их нельзя применять во всех ситуациях. Однако для проблемы останова требуется один общий алгоритм, который можно применить к любой программе на скелетном языке для определения, является ли она самозавершающейся. Наша способность использовать отдельные догадки для выявления самозавершаемости определенных программ никоим образом не подтверждает существования одного общего подхода, применимого ко всем случаям.
Неразрешимость проблемы останова. Теперь мы хотим показать, что решение проблемы останова выходит за пределы возможностей машин. Мы будем исходить из того, что для решения задачи потребуется алгоритм вычисления невычислимой функции. Входами этой функции являются закодированные варианты программ на скелетном языке, а выходами — значения 0 и 1. Точнее, мы определяем функцию так, что при подаче на вход самозавершающейся программы она порождает выходное значение 1, а для программы, не завершающейся самостоятельно, она выдает 0. Для краткости мы будем называть эту функцию функцией останова.
Наша задача — продемонстрировать, что функция останова не вычислима. Действовать мы будем от противного, то есть докажем, что утверждение ложно, показав, что оно не может быть правдивым. Докажем, что утверждение «функция останова вычислима» не может быть правдой. Доказательство продемонстрировано на рис. 3.
Рисунок 3 – Доказательство неразрешимости проблемы останова
Если функция останова вычислима, то (так как скелетный язык является универсальным языком программирования) должна существовать программа на скелетном языке для вычисления этой функции. Другими словами, эта программа должна останавливаться с выходом, равным 1, если ее вход — закодированный вариант самозавершающейся программы, и выдавать 0 в противном случае.
Для выполнения этой программы не требуется определять, какая переменная является входной, нужно просто присвоить всем переменным программы значение, равное закодированной версии тестируемой программы, ведь значение переменной, не являющейся входной, не влияет на конечное выходное значение. Мы делаем вывод, что если функция останова вычислима, то должна существовать программа на скелетном языке, которая останавливается с выходным значением 1, если все ее переменные инициализировались как закодированный вариант самозавершающейся программы, и завершается с выходом 0 в противоположном случае.
Предполагая, что выходная переменная программы — X (если это другая переменная, мы можем переименовать их), мы можем изменить программу, добавив в конце операторы
while X not 0 do;
end;
и получив новую программу. Эта новая программа должна быть либо самозавершающейся, либо нет. Однако мы увидим, что она не является ни той, ни другой.
В частности, если эта новая программа самозавершающаяся, и мы запустим ее с переменными, содержащими закодированное представление этой программы, то на момент, когда выполнение достигнет добавленного оператора while, значение переменной X будет равно 1. (До этого момента новая программа идентична исходной, которая выдает 1, если на вход было подано закодированное представление самозавершающейся программы.) Теперь программа навсегда войдет в цикл while-end, так как мы не предусмотрели уменьшение значения X в цикле. Однако это противоречит нашему предположению, что новая программа самозавершающаяся. Таким образом, мы можем сделать вывод, что новая программа не является самозавершающейся.
Если же новая программа не самозавершающаяся, и мы запустим ее, присвоив переменным закодированное значение программы, она достигнет добавленного оператора while со значением X, равным 0. (Это происходит потому, что операторы, предшествующие оператору while, генерируют выход программы, равный 0, если на вход подана кодировка не самозавершающейся программы.) В этом случае цикл while-end не будет выполнен, и программа остановится. Но это свойство самозавершающейся программы, поэтому мы делаем вывод, что новая программа самозавершающаяся, так же, как ранее увидели, что она не является самозавершающейся.
В итоге мы видим, что получили невозможную ситуацию: с одной стороны, программа может быть либо самозавершающейся, либо нет, а с другой — может не быть ни той, ни другой. Следовательно, предположение, которое привело к такому противоречию, ложно.
Мы делаем вывод, что функция останова невычислима, и, поскольку решение проблемы останова зависит от вычисления этой функции, можно утверждать, что ее решение лежит за пределами способностей любой алгоритмической системы. Подобные проблемы называются неразрешимыми проблемами (unresolvable problems).
В завершение необходимо связать полученные выводы с идеями, высказанными ранее - главной темой был вопрос, включают ли возможности вычислительных машин качества, необходимые для проявления интеллекта? Вспомните, что машинам подвластны только задачи с алгоритмическими решениями, а сейчас мы обнаружили, что существуют проблемы без алгоритмических решений. Следовательно, возникает вопрос, способен ли человеческий разум на большее, чем просто выполнение алгоритмических процессов. Если нет, то границы, которые мы очертили, также являются пределами для человеческого интеллекта. Нет необходимости говорить, что это очень спорный и волнующий многих вопрос. Если, например, разум людей — это не больше, чем запрограммированная машина, то можно сделать вывод, что люди не обладают свободой воли.