1. Рекурсивные множества: определения и примеры
Рекурсивные множества: определения и примеры
Представьте, что перед вами бесконечный ряд коробок, на каждой из которых написано натуральное число. Внутри некоторых коробок лежат золотые монеты, другие — пусты. У вас есть робот, которому можно дать номер коробки и спросить: «Есть ли там монета?». Если робот гарантированно дает ответ «Да» или «Нет» за конечное время для любого номера, мы имеем дело с объектом, который в математической логике и теории алгоритмов называется рекурсивным множеством. Но что произойдет, если для некоторых пустых коробок робот будет зависать навсегда, не в силах подтвердить отсутствие монеты? Этот нюанс разделяет мир вычислимого на два фундаментальных класса, изучение которых мы начнем с наиболее «предсказуемых» структур.
Фундаментальное определение и характеристическая функция
В классической теории алгоритмов, опирающейся на тезис Черча — Тьюринга, под множеством обычно понимается подмножество натуральных чисел . Мы называем множество рекурсивным (или вычислимым), если существует алгоритм, который для любого входного значения определяет, принадлежит ли этому множеству.
Чтобы перевести это интуитивное понятие на язык строгой математики, вводится понятие характеристической функции. Для любого множества характеристическая функция определяется следующим образом:
Здесь значение кодирует истинность утверждения о принадлежности, а — ложность. Множество называется рекурсивным тогда и только тогда, когда его характеристическая функция является везде определенной рекурсивной функцией.
Ключевое слово здесь — «везде определенная». Это означает, что алгоритм вычисления должен завершать работу за конечное число шагов для любого натурального . В контексте машин Тьюринга это эквивалентно утверждению, что существует машина, которая останавливается на любом входе, оставляя на ленте символ «1» (допуск) или «0» (отказ). Если мы можем построить такую машину, мы полностью контролируем состав множества: мы не просто «узнаем своих», но и «отсекаем чужих».
Классические примеры рекурсивных множеств
Простейшими примерами рекурсивных множеств являются пустое множество и само множество всех натуральных чисел . Их характеристические функции — это константы и соответственно, которые, очевидно, вычислимы. Однако для глубокого понимания стоит рассмотреть более содержательные примеры.
Конечные и коконечные множества
Любое конечное множество является рекурсивным. Алгоритм проверки прост: получив на вход , мы последовательно сравниваем его с каждым элементом из списка. Поскольку список конечен, процедура всегда завершится. Если совпадение найдено — ответ «Да», если список исчерпан без совпадений — ответ «Нет». Аналогично, коконечные множества (дополнения которых конечны) также рекурсивны. Если мы знаем, какие именно элементы не входят в множество, мы можем проверить входное число на принадлежность этому «черному списку».Множество четных чисел и арифметические прогрессии
Множество рекурсивно. Алгоритм деления на 2 с остатком эффективно реализуем на любой вычислительной модели. Более того, любое множество, задаваемое арифметической прогрессией или системой линейных сравнений, будет рекурсивным, так как проверка условий делимости всегда алгоритмизуема и конечна.Множество простых чисел
Множество является рекурсивным. Несмотря на то что простые числа распределены в натуральном ряду довольно сложно, для любого числа существует классический алгоритм проверки (например, перебор делителей от до ), который дает однозначный ответ за конечное время. Это важный момент: рекурсивность не требует «быстрого» алгоритма, она требует лишь его существования и гарантированной остановки.Степени двойки и другие разреженные множества
Множество рекурсивно. Чтобы проверить, является ли число степенью двойки, достаточно последовательно делить его на 2. Если мы придем к 1 — число принадлежит множеству. Если на каком-то этапе возникнет нечетный делитель, отличный от 1 — не принадлежит. Процесс логарифмически убывает, что гарантирует остановку.Граница между интуитивной и формальной вычислимостью
Важно понимать, что рекурсивность — это свойство самого множества, а не нашего знания о нем. Однако в учебных целях мы часто опираемся на наличие явного правила построения. Рассмотрим случай, который часто вызывает затруднения у студентов: является ли рекурсивным множество цифр в десятичной записи числа ?
Число иррационально и трансцендентно, его знаки вычисляются алгоритмически. Множество цифр, которые встречаются в его записи бесконечно много раз, — это подмножество . Поскольку любое подмножество конечного множества само конечно, оно автоматически является рекурсивным. Парадокс в том, что мы можем не знать точно, входит ли, скажем, цифра «7» в это множество бесконечно часто (хотя математики уверены, что — нормальное число), но само множество существует и оно конечно, а значит, рекурсивно. Это подчеркивает разницу между «мы знаем алгоритм» и «алгоритм существует в классе рекурсивных функций».
Рекурсивность и разрешимость
В литературе (включая пособие Ахтямова) термины «рекурсивное множество» и «разрешимое множество» часто используются как синонимы. Понятие разрешимости пришло из логики: проблема разрешима, если существует общий метод (алгоритм) для получения ответа «да» или «нет».
Когда мы говорим о множестве как о языке в алфавите , вопрос о рекурсивности множества превращается в вопрос о разрешимости проблемы принадлежности. Если мы можем написать программу, которая реализует характеристическую функцию , мы говорим, что проблема принадлежности к разрешима.
Нюансы: всюду определенность против частичности
Главная ловушка для новичка — смешение рекурсивных множеств с рекурсивно перечислимыми (о которых мы подробно поговорим в следующих лекциях). Чтобы закрепить понимание рекурсивности, нужно осознать: для рекурсивного множества алгоритм обязан «уметь говорить НЕТ».
Если у нас есть только процедура, которая останавливается и говорит «Да», когда , но уходит в бесконечный цикл, если , то такое множество нельзя называть рекурсивным. Оно лишь «полуразрешимо». Рекурсивность требует симметрии: и принадлежность, и непринадлежность должны подтверждаться за конечное время.
Рассмотрим пример из области программирования. Множество всех программ на языке С, которые содержат синтаксические ошибки, рекурсивно. Компилятор — это алгоритм, который за конечное время либо подтвердит корректность, либо укажет на ошибку. Однако множество всех программ, которые когда-либо завершат свою работу (проблема остановки), не является рекурсивным. Мы можем запустить программу и ждать остановки, но если она работает долго, мы никогда не узнаем — остановится ли она через секунду или будет крутиться вечно. Здесь нет «алгоритма отказа», а значит, нет и рекурсивности.
Формальные свойства характеристических функций
Для доказательства рекурсивности сложных структур часто используют свойства суперпозиции. Если функции и являются рекурсивными, то их композиция также рекурсивна. Для множеств это означает следующее: если мы можем выразить условие принадлежности к множеству через логические комбинации условий принадлежности к рекурсивным множествам и , то также будет рекурсивным.
Например, если и рекурсивны, то их характеристические функции и вычислимы. Тогда характеристическая функция их пересечения вычисляется как:
Поскольку произведение двух рекурсивных функций есть рекурсивная функция, пересечение рекурсивных множеств рекурсивно. Аналогичные конструкции для объединения и дополнения мы разберем в следующей главе, но этот пример наглядно показывает, почему аппарат рекурсивных функций так удобен для анализа множеств.
Проекции и декартовы произведения
Рекурсивность сохраняется и при переходе к декартовым произведениям. Если и рекурсивны, то их прямое произведение (которое можно рассматривать как подмножество пар чисел, закодированных одним числом через канторову нумерующую функцию) также будет рекурсивным.
Алгоритм проверки пары на принадлежность к тривиален:
Этот принцип «параллельного» или «последовательного» запуска двух гарантированно останавливающихся алгоритмов является фундаментом для построения всей иерархии вычислимых объектов.
Завершение обзора
Рекурсивные множества представляют собой «идеальный» случай в теории алгоритмов. Это те области данных, где мы обладаем полной информацией: мы можем безошибочно классифицировать любой объект. Однако математическая реальность такова, что большинство интересных множеств (например, множество истинных арифметических формул или множество останавливающихся программ) лежат за пределами этого класса.
Понимание рекурсивности как наличия всюду определенной характеристической функции позволяет нам перейти к изучению более сложных операций. В следующей лекции мы строго докажем, что класс рекурсивных множеств образует булеву алгебру — то есть он замкнут относительно всех стандартных теоретико-множественных операций. Это свойство делает рекурсивные множества чрезвычайно устойчивыми структурами, своего рода «базисом» вычислимости, от которого мы будем отталкиваться при штурме более сложных высот — рекурсивно перечислимых множеств.