Я не уверен на 100%, что это невозможно сделать с помощью двух наборов скобок. Однако, если ячейки ленты BF допускают неограниченные значения, достаточно трех наборов скобок. (Для простоты я также предполагаю, что мы можем переместить головку ленты влево от ее начальной точки, хотя, поскольку эта конструкция использует только конечную область ленты, мы могли бы снять это ограничение, добавив достаточно много >
команд в начале Программа.) Конструкция ниже требует предположения Артинуметь составлять произвольно большие программы; однако, даже если гипотеза Артина неверна, все равно будет возможно косвенно показать полноту по Тьюрингу посредством перевода интерпретатора языка, полного по Тьюрингу, в BF, используя конструкцию, приведенную ниже, и запуска произвольных программ, передавая их в качестве входных данных для этого интерпретатора.
Завершающим по Тьюрингу языком, который мы собираем в неограниченный BF, является Модель Водопада , которая является одной из простейших известных вычислительных моделей. Для людей, которые его еще не знают, он состоит из ряда счетчиков (и начальных значений для них) и функции от пар счетчиков до целых чисел; Выполнение программы состоит из многократного вычитания 1 из каждого счетчика, затем, если любой счетчик равен 0, добавление к каждому счетчику (программа написана таким образом, что это никогда не случается с несколькими счетчиками одновременно). За моей ссылкой есть доказательство полноты по Тьюрингу для этого языка. Без ограничения общности будем считать, что все счетчики имеют одинаковое значение самовозврата (т.е.fxf(x,y)yf(x,x) одинаково для всех ); это безопасное предположение, потому что для любого конкретного добавление одной и той же константы к каждому не изменит поведение программы.xxf(x,y)
Пусть будет числом счетчиков; без ограничения общности (предполагая гипотезу Артина), предположим, что имеет первообразный корень 2. Пусть будет , где - наименьшая степень 2, превышающая . Без ограничения общности будет меньше ( ограничено полиномиально, растет экспоненциально, поэтому любой достаточно большой будет работать).ppqp(1+s+s2)sp2q2p2q2pp
Расположение ленты следующее: мы нумеруем каждый счетчик целым числом (и без потери общности мы предполагаем, что есть один счетчик останова и нумеруем его ). Значение большинства счетчиков хранится в ленте , за исключением счетчика 0, который хранится в ленте . Для каждой нечетной ячейки ленты от ячейки -1 до включительно включительно0≤i<p22i2q2p+1+2p+1, эта ячейка ленты всегда содержит 1, если она не находится непосредственно слева от счетчика, в этом случае она всегда содержит 0. Ячейки ленты с четным номером, которые не используются в качестве счетчиков, имеют не имеющие значения (которые могут быть или не быть 0 ); и нечетные ячейки ленты вне указанного диапазона также имеют не относящиеся к делу значения. Обратите внимание, что установка ленты в соответствующее начальное состояние требует инициализации только конечного числа элементов ленты постоянными значениями, что означает, что мы можем сделать это с помощью последовательности <>+-
инструкций (фактически, только >+
необходимых), то есть без скобок. В конце этой инициализации мы перемещаем указатель ленты в ячейку -1.
Общая форма нашей программы будет выглядеть так:
инициализация корректировка[>>>[
>
×(2p−1) [
<
×(2p) ]>-]
<<<]
Инициализация помещает ленту в ожидаемую форму и указатель на ячейку -1. Это не ячейка слева от счетчика (0 не является степенью 2), поэтому она имеет значение 1, и мы входим в цикл. Инвариант цикла для этого самого внешнего цикла состоит в том, что указатель ленты находится (в начале и в конце каждой итерации цикла) на три ячейки слева от счетчика; можно видеть, что цикл, таким образом, будет выходить только в том случае, если мы на три ячейки слева от счетчика 2 (каждый счетчик имеет 1 три ячейки слева, так как наличие 0 означает, что позиции ленты двух счетчиков были 2 ячейки друг от друга, только две степени 2, которые отличаются на 2, являются и , и двоичное представление изменяется от строк с до строк2122q01s или наоборот по крайней мере четыре раза и, следовательно, не может быть 1 от степени 2).
Второй цикл многократно повторяет счетчики, уменьшая их. Инвариант цикла состоит в том, что указатель ленты всегда указывает на счетчик; таким образом, цикл завершится, когда какой-то счетчик станет равным 0. Уменьшение равно -
; путь от одного счетчика к другому более сложен. Основная идея состоит в том, что перемещение пробелов вправо от поместит нас в нечетную ячейку , которая находится справа от любого счетчика ( последний счетчик, положительный, потому что положительный); по модулю это значение конгруэнтно (по малой теореме Ферма) . Внутренняя петля многократно перемещается влево2p−12x2p+2x−12p2x−1x2p2x+12p пробелы, также не изменяющие индекс ячейки ленты по модулю , и должны в конечном итоге найти ячейку, конгруэнтную по модулю которая имеет значение (которое будет ячейкой слева от некоторого счетчика); из-за нашего примитивного корневого требования есть ровно одна такая ячейка ( соответствует по модулю , а соответствует для любого другой , где - дискретный логарифм по основанию 2 по модулю ). Дополнительно видно, что положение указателя ленты по модулю2p2x+12p2q−1−12p2log2,p(r)+1−12r−1rlog2,pp2pувеличивается на каждый раз вокруг средней петли. Таким образом, указатель ленты должен циклически переключаться между всеми счетчиками (в порядке их значений по модулю ). Таким образом, каждые итераций мы уменьшаем каждый счетчик (по мере необходимости). Если цикл прерывается на полпути через итерацию, мы возобновим уменьшение при повторном входе в цикл (поскольку остальная часть самого внешнего цикла не вносит никаких изменений в позицию указателя ленты).2p2pp
Когда счетчик достигает 0, средний цикл обрывается, что приводит нас к коду «корректировки». Это в основном просто кодировка ; для каждой пары , это добавляет на элемент ленты , который на одинаковом расстоянии слева / справа от текущего указателя на магнитной ленте в качестве счетчика «ы местоположения ленточного влево / вправо счетчика » ы местоположение ленты (а затем удаляет указатель ленты обратно туда, где она началась). Всякий раз, когда , это расстояние оказывается уникальным:f(x,y)f(x,y)yxx≠y
- Разница между двумя степенями 2 - это двоичное число, состоящее из строки 1 или более с, за которой следует строка 0 или более с (со значениями места начала числа и начала строки в зависимости от большего и меньшего соответственно и ); таким образом, все эти различия различны. * Что касается разности степени 2 и , она должна содержать не менее двух переходов между строками с и с (100xyq10q содержит не менее четырех таких переходов, вычитание может удалить только 2), таким образом, отличается от всех различий двух степеней двух, и эти различия, очевидно, также отличаются друг от друга.
Для мы, очевидно, находим, что пройденное расстояние равно 0. Но поскольку все равны, мы можем просто использовать это как корректировку для текущей ячейки. И можно видеть, что код корректировки, таким образом, реализует эффект «когда счетчик достигает 0» для каждого счетчика; все ячейки, которые фактически представляют счетчики, будут корректироваться на правильную величину, а все остальные настройки будут влиять на нечетные ячейки с четными номерами (разница между двумя четными числами четная), которые не влияют на поведение программы.x=yf(x,y)
Таким образом, теперь у нас есть рабочая компиляция любой программы в The Waterfall Model для BF (включая поведение при остановке, но не включая ввод-вывод, который не нужен для полноты по Тьюрингу), используя только три пары скобок и, таким образом, три пары скобок достаточно для полноты по Тьюрингу.