Каковы практические рекомендации по оценке "полноты Тьюринга" языка?

Я читал "что-это-Тьюринг-полной" и страница Википедии, но меня меньше интересует формальное доказательство, чем практические последствия завершения Тьюринга.

на самом деле я пытаюсь решить, можно ли использовать язык игрушек, который я только что разработал, в качестве языка общего назначения. Я знаю, что смогу доказать это, если смогу написать машину Тьюринга. Но я не хочу проходить через это упражнение, пока не буду полностью уверен в том, что успех.

существует ли минимальный набор функций, без которых невозможна полнота Тьюринга? Есть ли набор функций, который практически гарантирует полноту?

(Я предполагаю, что условное ветвление и читаемый / записываемый магазин памяти получат меня большую часть пути)


EDIT:

Я думаю, что я пошел по касательной, сказав "Turing Complete". Я пытаюсь с разумной уверенностью предположить, что недавно изобретенный язык с определенным набором функций (или, наоборот, виртуальная машина с определенным набором команд) сможет вычислить все, что стоит вычислить. Я знаю, что доказательство того, что вы можете построить машину Тьюринга, - это один из способов, но не единственный.

то,на что я надеялся,было набором рекомендаций, таких как: "если он может делать X, Y и Z, он может наверное сделать что-нибудь".

13 ответов


вам нужна какая-то форма динамической конструкции распределения (malloc илиnew или cons будет делать) и либо рекурсивные функции, либо какой-либо другой способ записи бесконечного цикла. Если у вас есть это и вы можете сделать что-нибудь интересное, вы почти наверняка завершите Тьюринга.

лямбда-исчисление эквивалентно по мощности машине Тьюринга, и если вы реализуете лямбда-исчисление это на самом деле довольно весело писать программы лямбда-исчисления. путь больше удовольствия, чем написание программы для машины Тьюринга!

единственным практическим следствием полноты Тьюринга, о котором я знаю, является то, что вы можете писать программы, которые не заканчиваются. Я использовал несколько языков специального назначения, которые гарантируют прекращение и поэтому являются не Turing-завершено. Иногда полезно отказаться от дополнительной выразительной силы в обмен на гарантированное прекращение.


'Тьюринг Полнота' описывает свойство способности выражать любые произвольные алгоритмические вычисления, в точку машина Тьюринга в первую очередь. Язык или логическую систему можно описать как "Turing Complete", если у нее есть это свойство. С практической точки зрения все языки программирования общего назначения - и удивительно большое количество специальных целей-могут сделать это для подходящего свободного определения (смотреть ниже.)

однако строгое определение полноты Тьюринга подразумевает бесконечную емкость хранилища, что, конечно, физически невозможно. Учитывая это, никакая физическая машина не может быть полной Тьюринга, но это ограничение обычно ослабляется (по крайней мере неофициально) при приписывании полноты Тьюринга языку программирования. Один тривиальный тест полноты Тьюринга для языка заключается в том, можно ли использовать язык для реализации машины Тьюринга тренажер.

примером широко распространенной системы, которая не является полной Тьюринга, является реляционная Алгебра, теоретическая основа SQL, описанная в статье Codd реляционная модель для больших совместно используемых банков данных. реляционная Алгебра имеет свойство Гедель Полноты, что означает, что он может выражать любые вычисления, которые могут быть определены в терминах исчисление предикатов первого порядка (т. е. простые логические выражения). Тем не менее, это не Тьюринг-полный, поскольку он не может выразить произвольное алгоритмическое вычисление.

обратите внимание, что большинство, если не все практические диалекты SQL расширяют чистую реляционную модель процедурными конструкциями в той мере, в какой они завершены определением, обычно применяемым к языкам программирования. Однако отдельный SQL-запрос по большому счету не является.

некоторыми более вопиющими примерами полных доменных языков Тьюринга являются Текс и sendmail.cf,. В последнем случае на самом деле есть знаменитый пример использования sendmail.cf to реализуйте универсальный симулятор машины Тьюринга.


Если вы можете написать Brainf$ переводчик на вашем языке, это Turing-complete. LOLCODE было доказано, что тьюринг-полный именно таким образом.


примеры языков, которые не являются Turing-complete часто имеют ограниченных циклов, например:

for i=1 to N {...}

но не хватает неограниченная петли, которые проверяют более общее состояние, например:

while bool_expr {...}

Если все возможные циклические конструкции ограничены, ваша программа обязательно завершится. И, хотя безусловная гарантия прекращения потенциально полезна, это также указывает на то, что язык не является Тьюринг-полный.

обратите внимание также, что прибивание все возможно циклические конструкции могут быть трудными; например, я уверен, что шаблоны C++ не предназначались для завершения Тьюринга...


Я не уверен, есть ли "минимальный набор функций", но чтобы доказать, что язык является полным Тьюринга, вам нужно только доказать, что он может эмулировать другую полную систему Тьюринга (не обязательно машину Тьюринга), пока другая система известна как полная Тьюринга. http://en.wikipedia.org/wiki/Turing_complete#Examples имеет целый список полных систем Тьюринга. Некоторые из них проще, чем машины Тьюринга.


Я хотел бы добавить одно предостережение к тому, что сказал Норман Рэмси: машина Тьюринга имеет бесконечную память, и, следовательно, языки программирования, которые считаются полными Тьюринга, только в предположении, что память также бесконечна.


Brainfuck является Turing полным и имеет только структуры цикла и увеличение/уменьшение памяти, поэтому этого достаточно.

с другой стороны, нет способа изменить какое-либо значение в лямбда-исчислении, но оно является полным Тьюрингом, поэтому ясно, что это можно сделать без изменяемой памяти.

скорее всего, ваша программа не имеет ничего общего с лямбда-исчислением, поэтому для практического ответа минимум должен быть

  1. способ записи переменная
  2. способ чтения переменной
  3. форма условного goto (оператор if, цикл while и т. д.)

Я не помню, чтобы видел что-нибудь вроде минимум функции для полноты Тьюринга. Однако, если ваш язык поддерживает циклы и условные ветви, шансы на то, что он является полным, хороши. Однако единственный способ доказать это-сравнить машину Тьюринга или другой полный язык Тьюринга.


Если вы можете реализовать машину Тьюринга (насколько они могут быть реализованы, поскольку они являются математическими конструкциями с неограниченной памятью [размер ленты бесконечен]), то вы можете быть уверены, что это Тьюринг полный.

признаки:

  • вы можете проверить память и манипулировать ею на основе текущего значения, а также использовать ее для управления потоком программы.
  • эта память может быть выделена память, строки, которые вы можете добавить, стек, который вы можете выделить память через рекурсию и т. д.
  • поток программы может быть через итерацию или через рекурсию на основе выбора.

любой язык, способный к non-termination, в значительной степени завершен Тьюрингом. Вы можете сделать язык, не заканчивающийся, способным, давая ему неограниченные циклические структуры (например, While loops или Goto, которые могут снова достичь себя), или давая ему общую рекурсию (позволяя функции вызывать себя без ограничений.)

после are turing complete, вы можете делать такие вещи, как интерпретировать другие языки Turing Complete, включая ваш собственный.

реальные вопрос "что в этом хорошего?"Если ваш язык будет использоваться в определенной области для решения конкретных проблем, может быть, лучше найти способ сформулировать решения на языке, который не является полным Тьюрингом и, следовательно, гарантированно даст ответ.

вы всегда можете добавить полноту Тьюринга, написав "сделайте это, то или другое; но сделайте это с результатом, предоставленным X" на любом другом языке Тьюринга, где X предоставляется полным не-Тьюринга язык.

конечно, если вы хотите использовать только один язык, это, вероятно, лучше быть полным Тьюринга...


существует ли минимальный набор функций, без которых невозможна полнота Тьюринга? Есть ли набор функций, который практически гарантирует полноту?

Да, вам нужно иметь поток управления, обусловленный данными: что часто выражается как if. Например,+-*/ карманный калькулятор не является полным Тьюрингом, так как нет способа выразить условные обозначения.

Вам также нужно иметь возможность выразить прыжок назад к более ранней точке в программе, поверх которой вы могли бы реализовать цикл. Например, BPF, который запрещает обратные прыжки, чтобы гарантировать завершение программы,также не является полным.

вам нужно некоторое хранилище, которое является читаемым и доступным для записи и произвольно большим. Например, язык, который имеет только две 32-разрядные переменные, ограничен в том, что он может вычислить. У вас есть много вариантов того, как структурировано хранилище: память, адресованная указателями, массивами, стеками, ячейками минусов, чистыми данными структур и т. д.

поверх них вы можете построить любой другой язык программирования: это может быть нелегко или быстро, но этого достаточно.


вы можете попробовать эмуляции OISC (Один Компьютер Команд-Набора). Если вы можете эмулировать одну из инструкций, то, поскольку эта единственная инструкция может быть использована для создания машины Turing Complete, вы доказали, что ваш язык также должен быть полным.


...чем в практическом смысле быть завершенным Тьюрингом.

Я сомневаюсь, что есть какие-либо практические последствия завершения Тьюринга.

Если вы посмотрите на некоторые примеры полных машин Тьюринга, например, оригинал машина Тьюринга, вы увидите, что они настолько далеки от того, чтобы быть полезными для реальных вычислений, что концепция должна представлять только теоретический интерес.