Практические нетурингово-полные языки? - PullRequest
41 голосов
/ 24 ноября 2008

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

Регулярные выражения используются для сопоставления строк и конечные автоматы используются при lexing , но мне интересно, есть ли более общий, широко используемый язык, не завершено?

edit: Я должен пояснить, что под «общим назначением» я не обязательно хочу писать все алгоритмы остановки на языке (я не думаю, что такой язык существует) но я подозреваю, что в останавливающих доказательствах есть общие темы, которые можно обобщить, чтобы создать язык, на котором гарантированно останавливаются все алгоритмы.

Существует также другой способ решения этой проблемы - устранение необходимости в теоретически бесконечной памяти. После того, как вы ограничите объем памяти, который разрешен машине, число состояний, в которых находится машина, является конечным и счетным, и, следовательно, вы можете определить, остановится ли алгоритм (не позволяя машине перейти в состояние, в котором он находился до этого). ).

Ответы [ 8 ]

50 голосов
/ 05 июля 2009

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

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

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

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

31 голосов
/ 24 ноября 2008

BlooP (сокращение от B округленный loop ) - интересный язык, не полный по Тьюрингу По сути, это язык, полный Тьюринга, с одним (основным) предупреждением: каждый цикл должен содержать ограничение на число итераций. Бесконечные циклы не допускаются. В результате проблема остановки может быть решена для программ BlooP.

14 голосов
/ 24 ноября 2008

Проблема не в машине Тьюринга, а в «алгоритме». Причина, по которой вы не можете предсказать, остановится ли алгоритм или нет, заключается в следующем:

function confusion()
{
    if( halts( confusion ) )
    {
        while True:
            no-op
    }
    else
        return;
}

Любой язык, который не может выполнять рекурсию или циклы, на самом деле не был бы "универсальным".

Регулярные выражения и конечные автоматы - это одно и то же! Лексирование и сопоставление строк - это одно и то же! Причина, по которой FSM останавливаются, заключается в том, что они никогда не зацикливаются; они просто передают вход char-by-char и выходят.

EDIT:

Для многих алгоритмов очевидно, остановятся они или нет.

например:

function nonhalting()
{
    while 1:
        no-op
}

Эта функция явно никогда не останавливается.

И эта функция, очевидно, останавливается:

function simple_halting_function()
{
    return 1;
}

Итак, суть: вы МОЖЕТЕ гарантировать, что ваш алгоритм остановится, просто спроектируйте его так, чтобы он работал.

Если вы не уверены, будет ли алгоритм все время останавливаться; тогда вы, вероятно, не сможете реализовать его ни на одном языке, который гарантирует «остановку».

9 голосов
/ 10 сентября 2009

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

8 голосов
/ 24 ноября 2008

Оказывается, довольно легко быть полным. Например, вам нужны только 8 инструкций ala BrainF ** k , и более того, вам нужно всего лишь одна инструкция .

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

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

2 голосов
/ 15 декабря 2011

Правильный способ сделать это, ИМХО, состоит в том, чтобы иметь язык, полный по Тьюрингу, но обеспечить систему для определения семантики, поддающейся обработке проверяющим средством проверки.

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

В качестве отступления в моем производственном компиляторе у меня есть рекурсии, которые, я знаю, наверняка НЕ ​​остановят определенные входные данные ... Я использую неприятный хак, чтобы остановить это: счетчик с "разумным" пределом. К вашему сведению, реальный код задействован в мономорфизированном полиморфном коде, а бесконечное расширение происходит при использовании полиморфной рекурсии. Haskell ловит это, мой компилятор для Феликса - нет (это ошибка в компиляторе, которую я не знаю, как исправить).

Исходя из моего общего аргумента. Я бы наверняка хотел узнать, какие аннотации будут полезны для заявленной цели: у меня есть контроль над языком и компилятором, поэтому я мог бы легко добавить такую ​​поддержку, если бы только знал что именно добавить :) Я видел добавление предложений «инвариант» и «вариант» к циклам для этой цели, хотя я не думаю, что язык расширился до использования этой информации для доказательства завершения (скорее он проверил инвариант и вариант во время выполнения, если я правильно помню).

Может быть, это заслуживает другого вопроса ..

2 голосов
/ 25 ноября 2008

«Устранить необходимость теоретически бесконечной памяти». -- Ну, да. Любой физический компьютер ограничен энтропией вселенной и даже до этого скоростью света (== максимальная скорость, с которой может распространяться информация).

Еще проще, на физически реализуемом компьютере, просто отслеживать потребление ресурсов и ограничивать его. (т. е. когда потребление памяти или времени> MY_LIMIT, завершить процесс).

Если то, что вы спрашиваете, является чисто математическим / теоретическим решением, как вы определяете «общее назначение»?

0 голосов
/ 24 ноября 2008

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

...