Тьюринг-полнота — различия между версиями
Romanosov (обсуждение | вклад) м (→SQL) |
Romanosov (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
+ | ==Введение== | ||
+ | |||
Говорят, что задача является '''Тьюринг-полной''', если её можно решить, используя только [[Машина Тьюринга|машину Тьюринга]] или любую систему, являющуюся Тьюринг-эквивалентной. | Говорят, что задача является '''Тьюринг-полной''', если её можно решить, используя только [[Машина Тьюринга|машину Тьюринга]] или любую систему, являющуюся Тьюринг-эквивалентной. | ||
{{Определение | {{Определение | ||
Строка 8: | Строка 10: | ||
В теории вычислимости ''исполнитель'' (множество вычисляющих элементов) называется '''Тьюринг-полным''', если на нём можно реализовать любую вычислимую функцию. Другими словами, для каждой вычислимой функции существует вычисляющий её элемент (например, машина Тьюринга) или программа для исполнителя, а все функции, вычисляемые множеством вычислителей, являются вычислимыми функциями (возможно, при некотором кодировании входных и выходных данных). | В теории вычислимости ''исполнитель'' (множество вычисляющих элементов) называется '''Тьюринг-полным''', если на нём можно реализовать любую вычислимую функцию. Другими словами, для каждой вычислимой функции существует вычисляющий её элемент (например, машина Тьюринга) или программа для исполнителя, а все функции, вычисляемые множеством вычислителей, являются вычислимыми функциями (возможно, при некотором кодировании входных и выходных данных). | ||
− | Любой полный по Тьюрингу язык достаточно универсальный, чтобы имитировать все другие (хотя и с потенциальным замедлением в работе). Такие языки эквивалентны в рамках вычислений, которые могут произвести. Полные по Тьюрингу языки настолько распространены, что их можно обнаружить даже в примитивных на первый взгляд системах, например, клеточных автоматах или мозаичных системах. | + | Любой полный по Тьюрингу язык достаточно универсальный, чтобы имитировать все другие (хотя и с потенциальным замедлением в работе). Такие языки эквивалентны в рамках вычислений, которые могут произвести. Полные по Тьюрингу языки настолько распространены, что их можно обнаружить даже в примитивных на первый взгляд системах, например, [Линейный клеточный автомат, эквивалентность МТ|клеточных автоматах] или мозаичных системах. |
На практике полнота по Тьюрингу — идеализация. Компьютеры имеют ограниченное количество памяти и будут работать ограниченное количество времени, прежде чем их выключат. | На практике полнота по Тьюрингу — идеализация. Компьютеры имеют ограниченное количество памяти и будут работать ограниченное количество времени, прежде чем их выключат. | ||
Строка 17: | Строка 19: | ||
Если на языке программирования можно реализовать машину Тьюринга, то такой язык Тьюринг-полон, и наоборот. Возможность реализации машины Тьюринга на конкретном языке программирования можно грубо описать как перечень требований, которым этот язык должен для этого удовлетворять: | Если на языке программирования можно реализовать машину Тьюринга, то такой язык Тьюринг-полон, и наоборот. Возможность реализации машины Тьюринга на конкретном языке программирования можно грубо описать как перечень требований, которым этот язык должен для этого удовлетворять: | ||
− | * Конечность (нет бесконечных символьных множеств и пр.) | + | * Конечность (нет бесконечных символьных множеств и пр.). |
− | * Фиксированное описание | + | * Фиксированное описание. |
− | * Всегда достаточный объём доступной памяти — в идеале здесь имеется в виду бесконечная память, однако физические рамки не позволяют сделать память ЭВМ бесконечной, поэтому она просто должна быть "always big enough". | + | * Всегда достаточный объём доступной памяти — в идеале здесь имеется в виду бесконечная память, однако физические рамки не позволяют сделать память ЭВМ бесконечной, поэтому она просто должна быть ''"always big enough"''. |
− | * Неограниченность времени выполнения | + | * Неограниченность времени выполнения. |
− | * Возможность функциональной композиции (вызов одной функции из другой, рекурсия) | + | * Возможность функциональной композиции (вызов одной функции из другой, рекурсия). |
− | * Циклы while с прерыванием или эквивалентные им | + | * Циклы <tex>{\bf while}</tex> с прерыванием или эквивалентные им. |
− | * Возможность останавливать выполнение (halt) или каким-то образом подавать сигнал о результатах выполнения | + | * Возможность останавливать выполнение (''halt'') или каким-то образом подавать сигнал о результатах выполнения. |
− | * Представление множества натуральных чисел, понятие | + | * Представление множества натуральных чисел, понятие нуля и следующего числа. Возможны другие подобные системы. |
* Поддержка входных и выходных данных (I/O), причём без ограничений в объёме. Если любая программа, написанная на каком-то языке программирования, принимает на вход не более фиксированного n бит данных и возвращает не более n бит, этот язык не может быть Тьюринг-полным. | * Поддержка входных и выходных данных (I/O), причём без ограничений в объёме. Если любая программа, написанная на каком-то языке программирования, принимает на вход не более фиксированного n бит данных и возвращает не более n бит, этот язык не может быть Тьюринг-полным. | ||
Строка 37: | Строка 39: | ||
==Тьюринг-полнота и неполнота некоторых языков программирования== | ==Тьюринг-полнота и неполнота некоторых языков программирования== | ||
− | Доказать Тьюринг-полноту языка программирования можно, предложив способ реализации машины Тьюринга на этом языке. Кроме того, можно предложить интерпретатор | + | Доказать Тьюринг-полноту языка программирования можно, предложив способ реализации машины Тьюринга на этом языке. Кроме того, можно предложить на нём интерпретатор Тьюринг-полного языка. |
===Assembly language=== | ===Assembly language=== | ||
− | Язык Ассемблера | + | Язык Ассемблера достаточно примитивен относительно языков программирования высокого уровня: он рассчитан на архитектуру с конечной памятью и работает с конечным набором регистров. Однако, не был бы он полным по Тьюрингу, не были бы Тьюринг-полны и любые высокоуровневые языки программирования. |
Всё необходимое для машины Тьюринга на asm можно сделать примерно так: | Всё необходимое для машины Тьюринга на asm можно сделать примерно так: | ||
− | ADDS r0, r0, #1 ; сдвиг ленты вправо | + | ADDS r0, r0, #1 ; <font color=green>сдвиг ленты вправо</font> |
− | ADDS r0, r0, #-1 ; сдвиг ленты влево | + | ADDS r0, r0, #-1 ; <font color=green>сдвиг ленты влево</font> |
− | ADDS [r0], [r0], #1 ; инкремент значения, на которое "указывает" головка ленты | + | ADDS [r0], [r0], #1 ; <font color=green>инкремент значения, на которое "указывает" головка ленты</font> |
− | ADDS [r0], [r0], #-1 ; декремент значения, на которое "указывает" головка ленты | + | ADDS [r0], [r0], #-1 ; <font color=green>декремент значения, на которое "указывает" головка ленты</font> |
− | И далее использовать инструкцию | + | И далее использовать инструкцию <tex>\mathrm{BEQ}</tex> или ей подобную, чтобы выполнять определённую последовательность команд при определённом текущем значении, таким образом обеспечив ветвление. |
===Pascal=== | ===Pascal=== | ||
− | Язык Pascal позволяет смоделировать ленту машины Тьюринга с помощью двунаправленного списка из переменных, создаваемых оператором | + | Язык Pascal позволяет смоделировать ленту машины Тьюринга с помощью двунаправленного списка из переменных, создаваемых оператором <tex>\mathrm{new}</tex>, семантика которого не предполагает отказа в создании переменной. Также с помощью списков |
можно смоделировать сколь угодно большие числа. Стандарт не накладывает никаких ограничений: указательный тип абстрактен, множество значений указательного типа языком не ограничено. | можно смоделировать сколь угодно большие числа. Стандарт не накладывает никаких ограничений: указательный тип абстрактен, множество значений указательного типа языком не ограничено. | ||
В Паскале есть еще один тип данных с неограниченным множеством значений, файловый, также пригодный для моделирования ленты машины Тьюринга и представления больших чисел. Достаточно утверждений для очевидности Тьюринг-полноты языка Pascal. | В Паскале есть еще один тип данных с неограниченным множеством значений, файловый, также пригодный для моделирования ленты машины Тьюринга и представления больших чисел. Достаточно утверждений для очевидности Тьюринг-полноты языка Pascal. | ||
Строка 196: | Строка 198: | ||
|[[Файл:gcc_asm.png|400px|thumb|Результат работы GCC]] | |[[Файл:gcc_asm.png|400px|thumb|Результат работы GCC]] | ||
|[[Файл:mov_asm.png|400px|thumb|Результат работы M/o/Vfuscator]] | |[[Файл:mov_asm.png|400px|thumb|Результат работы M/o/Vfuscator]] | ||
− | |[[Файл:Demo_mov.gif | + | |- |
+ | |[[Файл:Demo_mov.gif|thumb|500px|Простые числа с использованием одной инструкции]] | ||
|} | |} | ||
Строка 203: | Строка 206: | ||
Нововведения новых версий HTML/CSS позволяют построить<ref>[http://eli.fox-epste.in/rule110-full.html Rule 110]</ref> [https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%BE_110 правило 110], которое является Тьюринг-полным. | Нововведения новых версий HTML/CSS позволяют построить<ref>[http://eli.fox-epste.in/rule110-full.html Rule 110]</ref> [https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%BE_110 правило 110], которое является Тьюринг-полным. | ||
− | === | + | ===Excel=== |
− | === | + | ===Тьюринг-полнота в играх=== |
− | + | Minecraft<ref>[https://www.youtube.com/watch?v=7sNge0Ywz-M|Demonstrating the CPU. Then coughing a lot. Sorry about that. I may be dying.]</ref> | |
− | = | + | Little Big Planet<ref>[https://www.youtube.com/watch?v=13GOFa1C4e4| LittleBigLife — The Game of Life in LittleBigPlanet]</ref> |
− | = | + | Super Mario World<ref>[https://www.youtube.com/watch?v=hB6eY73sLV0 SNES Code Injection -- Flappy Bird in SMW]</ref> |
+ | |||
+ | [[Неразрешимость игры Braid|Braid]] | ||
==Тьюринговская трясина== | ==Тьюринговская трясина== | ||
Строка 223: | Строка 228: | ||
==См. также== | ==См. также== | ||
− | [[Машина Тьюринга]] | + | * [[Машина Тьюринга]] |
==Примечания== | ==Примечания== | ||
Строка 251: | Строка 256: | ||
[[Категория: Теория формальных языков]] | [[Категория: Теория формальных языков]] | ||
[[Категория: Теория вычислимости]] | [[Категория: Теория вычислимости]] | ||
+ | [[Категория: Вычислительные формализмы]] | ||
+ | [[Категория: Машина Тьюринга]] |
Версия 23:55, 8 января 2017
Содержание
Введение
Говорят, что задача является Тьюринг-полной, если её можно решить, используя только машину Тьюринга или любую систему, являющуюся Тьюринг-эквивалентной.
Определение: |
Вычислительное устройство является Тьюринг-эквивалентным, если оно может эмулировать машину Тьюринга. |
Зачастую Тьюринг-эквивалентные языки программирования называют Тьюринг-полными.
В теории вычислимости исполнитель (множество вычисляющих элементов) называется Тьюринг-полным, если на нём можно реализовать любую вычислимую функцию. Другими словами, для каждой вычислимой функции существует вычисляющий её элемент (например, машина Тьюринга) или программа для исполнителя, а все функции, вычисляемые множеством вычислителей, являются вычислимыми функциями (возможно, при некотором кодировании входных и выходных данных).
Любой полный по Тьюрингу язык достаточно универсальный, чтобы имитировать все другие (хотя и с потенциальным замедлением в работе). Такие языки эквивалентны в рамках вычислений, которые могут произвести. Полные по Тьюрингу языки настолько распространены, что их можно обнаружить даже в примитивных на первый взгляд системах, например, [Линейный клеточный автомат, эквивалентность МТ|клеточных автоматах] или мозаичных системах.
На практике полнота по Тьюрингу — идеализация. Компьютеры имеют ограниченное количество памяти и будут работать ограниченное количество времени, прежде чем их выключат.
Критерии Тьюринг-полноты
Если на языке программирования можно реализовать машину Тьюринга, то такой язык Тьюринг-полон, и наоборот. Возможность реализации машины Тьюринга на конкретном языке программирования можно грубо описать как перечень требований, которым этот язык должен для этого удовлетворять:
- Конечность (нет бесконечных символьных множеств и пр.).
- Фиксированное описание.
- Всегда достаточный объём доступной памяти — в идеале здесь имеется в виду бесконечная память, однако физические рамки не позволяют сделать память ЭВМ бесконечной, поэтому она просто должна быть "always big enough".
- Неограниченность времени выполнения.
- Возможность функциональной композиции (вызов одной функции из другой, рекурсия).
- Циклы с прерыванием или эквивалентные им.
- Возможность останавливать выполнение (halt) или каким-то образом подавать сигнал о результатах выполнения.
- Представление множества натуральных чисел, понятие нуля и следующего числа. Возможны другие подобные системы.
- Поддержка входных и выходных данных (I/O), причём без ограничений в объёме. Если любая программа, написанная на каком-то языке программирования, принимает на вход не более фиксированного n бит данных и возвращает не более n бит, этот язык не может быть Тьюринг-полным.
Тьюринг-полнота и неполнота некоторых языков программирования
Доказать Тьюринг-полноту языка программирования можно, предложив способ реализации машины Тьюринга на этом языке. Кроме того, можно предложить на нём интерпретатор Тьюринг-полного языка.
Assembly language
Язык Ассемблера достаточно примитивен относительно языков программирования высокого уровня: он рассчитан на архитектуру с конечной памятью и работает с конечным набором регистров. Однако, не был бы он полным по Тьюрингу, не были бы Тьюринг-полны и любые высокоуровневые языки программирования.
Всё необходимое для машины Тьюринга на asm можно сделать примерно так:
ADDS r0, r0, #1 ; сдвиг ленты вправо ADDS r0, r0, #-1 ; сдвиг ленты влево ADDS [r0], [r0], #1 ; инкремент значения, на которое "указывает" головка ленты ADDS [r0], [r0], #-1 ; декремент значения, на которое "указывает" головка ленты
И далее использовать инструкцию
или ей подобную, чтобы выполнять определённую последовательность команд при определённом текущем значении, таким образом обеспечив ветвление.Pascal
Язык Pascal позволяет смоделировать ленту машины Тьюринга с помощью двунаправленного списка из переменных, создаваемых оператором
, семантика которого не предполагает отказа в создании переменной. Также с помощью списков можно смоделировать сколь угодно большие числа. Стандарт не накладывает никаких ограничений: указательный тип абстрактен, множество значений указательного типа языком не ограничено. В Паскале есть еще один тип данных с неограниченным множеством значений, файловый, также пригодный для моделирования ленты машины Тьюринга и представления больших чисел. Достаточно утверждений для очевидности Тьюринг-полноты языка Pascal.C
В языке C нет высокоуровневого понятия переменной (в смысле Паскаля), есть объекты (object), хранящиеся в памяти как последовательно расположенные байты,имеющие адрес (байты в свою очередь состоят из неадресуемых битов). Целые типы ограничены (конечное множество значений), указатель отождествляется с адресом, постулируется возможность хранить адрес в целочисленной переменной (int или long — зависит от реализации), откуда следует ограниченность множества значений указателей, а стало быть, и ограниченность адресного пространства C-машины. То есть язык C, как и язык ассемблера, ориентирован на архитектуру с конечной памятью. Файл не является типом данных языка C, в отличие от Паскаля. Это вещь из окружения, для работы с которой есть операции над потоками в виде набора библиотечных функций. Тип fpos_t, принятый в стандарте C для позиционирования файлов, постулируется как «отличный от массива тип данных (object type)». Следовательно, множество значений этого типа конечно, а значит, максимальная длина файла в языке C ограничена сверху.
SQL
Сам по себе SQL не считается полным по Тьюрингу языком. Однако, у него существует множество расширений, позволяющих делать рекурсивные запросы, циклы, списки, деревья и пр., например,c с помощью PostgreSQL[1]. Тем не менее, всё ещё остаётся ограниченное query execution time.
HTML
HTML можно назвать языком программирования только в контексте формальной полемики. На деле он является языком гипертекстовой разметки и ни чем больше. Т. е. на HTML можно совершить только некоторую ограниченную совокупность действий, интерпретируемых браузером, однако никто не запрещает сделать язык, идентичный по синтаксису с HTML, но интерпретируемый совершенно по другому таким образом, чтобы он был полным по Тьюрингу.
Некоторые другие ЯП
Название языка | Год изобретения | Парадигма | Уровень | Машинно-зависимость | Полнота по Тьюрингу |
---|---|---|---|---|---|
C | 1972 | Процедурный | Низкий | зав. от ISO | Да |
C++ | 1983 | Мультипарадигменный | Высокий/Низкий | Нет | Да |
Язык Ассемблера | 1950 | Полнофункциональный | Низкий | Да | Да |
SQL | 1989 | Декларативный | Высокий | Нет | Нет |
Haskell | 1990 | Функциональный | Высокий | Нет | Да |
HTML | 1986 | Декларативный | Высокий | Нет | Нет |
CSS | 1996 | Декларативный | Высокий | Нет | Нет |
Java | 1995 | Объектно-ориентированный | Высокий | Нет | Да |
JavaScript | 1965 | Объектно-ориентированный | Высокий | Нет | Да |
Python | 1991 | Объектно-ориентированный | Высокий | Нет | Да |
XML | 1998 | Декларативный | Высокий | Нет | Нет |
Brainfuck | 1993 | Эзотерический | Низкий | Да | Да |
Whitespace | 2003 | Эзотерический | Низкий | Да | Да |
Интересные случаи полноты по Тьюрингу
Шаблоны C++
Шаблоны C++ позволяют производить сложные вычисления ещё на стадии компиляции программы. Впервые это было продемонстрировано Эрвином Унрухом, который реализовал рекурсивный алгоритм распознавания простых чисел в процессе компиляции. Позже в статье Университета Индиана было продемонстрировано кодирование машины Тьюринга в шаблонах C++[2].
Java Generics
Аналогично C++ Templates, Generics, несмотря на свои отличия, тоже оказались полными по Тьюрингу, что было подтверждено Раду Григор в одной из статей Кентского Университета[3].
URISC
URISC (от англ. Ultimate RISC) — предельный случай процессора типа RISC (буквально: компьютер с предельно сокращённым набором инструкций), который умеет выполнять одну-единственную инструкцию. Обычно это «вычесть и пропустить следующую инструкцию, если вычитаемое было больше уменьшаемого» (англ. «reverse-subtract and skip if borrow»). Аналогичная концепция, основанная именно на «вычесть и перейти, если результат не положительный» (англ. «subtract and branch unless positive»), называется SUBLEQ.
URISC также известен в современной литературе как OISC (англ. One Instruction Set Computer) и является полным по Тьюрингу.
mov
Утилита M/o/Vfuscator превращает любую программу на языке C в огромную последовательность из инструкций mov[4].
HTML5 + CSS3
Нововведения новых версий HTML/CSS позволяют построить[5] правило 110, которое является Тьюринг-полным.
Excel
Тьюринг-полнота в играх
Minecraft[6]
Little Big Planet[7]
Super Mario World[8]
Тьюринговская трясина
Тьюринговская трясина — жаргонное общее название для языков программирования, которые Тьюринг-полны, но обладают крайне примитивными синтаксисом и семантикой. Они неудобны для практического программирования (из-за трудности написания программ и низкой производительности), зато хорошо подходят для некоторых других задач (доказательство невычислимости некоторых функций, иллюстрация базовых принципов программирования и т. д.). Поэтому они интересны для информатики.
Первыми представителями "трясины" были лямбда-исчисление, комбинаторная логика и сама машина Тьюринга.
Многие эзотерические языки программирования также являются «трясинами Тьюринга» (напр. Brainfuck, Spoon, Malbolge, Whitespace).
См. также
Примечания
- ↑ High Performance with PostgreSQL 8.4
- ↑ C++ Templates are Turing-complete
- ↑ Java Generics are Turing-complete
- ↑ M/o/Vfuscator
- ↑ Rule 110
- ↑ the CPU. Then coughing a lot. Sorry about that. I may be dying.
- ↑ LittleBigLife — The Game of Life in LittleBigPlanet
- ↑ SNES Code Injection -- Flappy Bird in SMW