Есть ли достаточно хорошее решение проблемы остановки?

Известно, что проблема остановки не может иметь определенного решения, которое: а) возвращает true ‹==> программа действительно останавливается, и б) обрабатывает любой ввод, но мне было интересно, есть ли достаточно хорошие решения проблемы, те, которые могут идеально справляться с определенными типами программ, или могут определить, когда они не могут правильно решить проблему, или те, которые верны в большом проценте случаев, и так далее ....

Если да, то насколько они хороши и на какие идеи / ограничения опираются?


person EpsilonVector    schedule 18.03.2010    source источник
comment
Разве проблема остановки - это скорее мысленный эксперимент, демонстрирующий пределы вычислимости, чем реальная проблема?   -  person    schedule 18.03.2010
comment
Нет, это довольно полезная проблема. Вот несколько вопросов из реальной жизни, на которые может ответить проблема остановки: находится ли моя программа в бесконечном цикле или она будет завершена? Будет ли компилироваться эта программа на C ++? Сколько страниц в моем документе PostScript?   -  person Gabe    schedule 18.03.2010
comment
За исключением того, что проблема с остановкой в ​​целом не решаема. Вы говорите о конкретных программах с определенными входами, поэтому можно определить, остановятся ли они.   -  person    schedule 18.03.2010
comment
Вы говорите о конкретных программах с определенными входами. Это не имеет значения. Общность проблемы остановки проистекает из того факта, что мы говорим об этом, не придавая никакого значения входным данным, а не потому, что мы обсуждаем сценарий, в котором мы должны принимать ЛЮБОЙ вход. Вполне возможно иметь проблему, которая принимает только подмножество всех возможных входных данных и все же может определить вычислимое сокращение от проблемы остановки до нее (что означает, что ее решение решает проблему остановки).   -  person EpsilonVector    schedule 15.05.2010
comment
Поздно к вечеринке, но, вероятно, теперь это должно быть на информатике   -  person    schedule 18.12.2013
comment
@MikeW Это вполне может быть, но мы не переносим сообщения старше 30 дней. (На самом деле в таких случаях нет интерфейса).   -  person Andrew Barber    schedule 18.12.2013


Ответы (6)


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

person Daniel Pryden    schedule 18.03.2010
comment
Существуют и другие методы анализа завершения, которые иногда могут определять, будут ли программы остановлены, например Рекурсия Вальтера. - person Anderson Green; 16.06.2019

те, которые могут отлично справляться с определенными типами программных потоков

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

void run(int x)
{
    while(x != 0)
    {
        x = x > 0 ? x-2 : x+2;
    }
}

Решение короче, чем сам код.

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

Опять же просто: возьмите программу, указанную выше, и заставьте ее ответить «нет», если программа не соответствует фиксированной узкой схеме.

или тот, который верен в большинстве случаев

Как вы определяете «высокий» процент из бесконечного набора возможных входов?

person Michael Borgwardt    schedule 18.03.2010
comment
Вопрос OP действительно становится интересным для нетривиальных программ. - person shoosh; 18.03.2010

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

Рассмотрим следующий небольшой фрагмент:

var x := 20;
while (x >= 0) {
    x := x - 1
}

Здесь мы видим, что x уменьшается каждый раз при выполнении цикла, и что цикл завершится после x ‹0 (очевидно, это не очень строго, но вы поняли идею). Следовательно, мы можем использовать x как вариант.

А как насчет более сложного примера? Рассмотрим конечный список целых чисел L = [L [0], L [1], ..., L [n]]. in(L, x) истинно, если x является членом L. Теперь рассмотрим следующую программу:

var x := 0;
while (in(L, x)) {
    x := x + 1
}

Это будет искать среди натуральных чисел (0, 1, 2, ...) и остановится, как только будет найдено значение для x, которого нет в L. Итак, как мы докажем, что это завершается? В L должно быть максимальное значение - назовем его max (L). Затем мы можем определить наш вариант как max(L) - x. Чтобы доказать прекращение, мы сначала должны доказать, что max(L) - x всегда убывает - это не слишком сложно, поскольку мы можем доказать, что x всегда увеличивается. Затем мы должны доказать, что цикл завершится, когда max(L) - x < 0. Если max(L) - x < 0, то max(L) < x, что означает, что x не может быть в L, и поэтому цикл завершится.

person Michael Williamson    schedule 18.03.2010

Смотрите документы, связанные с проектом Терминатор:

http://research.microsoft.com/en-us/um/cambridge/projects/terminator/

person SK-logic    schedule 18.03.2010

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

Чтобы дать вам представление о том, насколько сложна проблема «насколько они хороши», вот вопрос, представляющий большой теоретический интерес: для данного размера N, сколько машин размера N останавливается? Это невычислимо (потому что машина, которая могла бы вычислить, могла бы использоваться для решения проблемы остановки) и неизвестна для N> 4.

person Beta    schedule 18.03.2010

Да, просто сделайте пространство состояний конечным, и это (теоретически) возможно для всех входов. (Просто переберите все возможности.)

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

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

person Chris Lercher    schedule 18.03.2010