Существует ли язык программирования, где вам всегда гарантируется завершение?
Если у вас есть только команды if/else, вы можете быть уверены, что программа завершится?
Существует ли язык программирования, где вам всегда гарантируется завершение?
Если у вас есть только команды if/else, вы можете быть уверены, что программа завершится?
Да, конечно, есть некоторые не-Тьюринговые языки, которые гарантируют завершение (или, по крайней мере, предоставляют подмножества с такой гарантией):
В большинстве случаев это достигается только за счет рекурсивных вызовов по строгим субтерминалам (и, с помощью арифметики Церкви, это означает, что также всегда уменьшается положительный целочисленный счетчик).
И, что удивительно, это не так ограничено, как кажется, и эти языки прекрасно подходят для решения очень широкого круга проблем.
Проект Terminator может быть интересным.
Язык программирования, гарантирующий завершение, не turing complete. [В противном случае проблема Halting Problem была бы тривиальной проблемой, которая, как доказано, не относится к машинам turing].
Вы можете ссылаться на регулярные выражения как слабый язык программирования для этой проблемы, и у него есть функция, которую вы ищете.
Datalog является примером реального языка программирования, для которого заканчивается каждая программа.
Вы не можете предсказать, когда программа остановится для общего случая программы (это то, что называется The Halting Problem".
"Стандартный" язык программирования эквивалентен машине Тьюринга, поэтому вы не можете предсказать, остановится ли программа, написанная на этом языке.
Если вы ограничиваете свой язык программирования, условия меняются, и в некоторых случаях программа остановки для такой модели может быть разрешима, но это не относится к языку программирования общего пользования.
Как вы уже видели (в других ответах), программа, которая так же сильна, как машина turing, не может быть предсказана, если она остановится или нет. Хотя наши компьютеры не обрабатывают машины (это едва ли ограниченные линейные автоматы, и если вы действительно хотите быть точными, это просто DFA с огромным количеством состояний. Это из-за конечной памяти)
Итак, в теории, вы можете определить, может ли какая-либо программа на наших обычных компьютерах остановиться или нет. Однако для этой программы может потребоваться O(2^(32)*n)
(n - размер памяти) и время практически невозможно. (Если вам нужен алгоритм, запустите программу и сохраните состояние всей памяти на каждом шаге, проверьте, не достиг ли вы того же моментального снимка памяти. Поскольку память ограничена, этот алгоритм остановится).
Итак, теперь вопрос сводится к тому, каковы свойства языка, которые предсказуемы, скажем, полиномиальным временем. Ответ на этот вопрос не так прост, но несколько примеров легко приходят на ум:
Программа, написанная на языке, который всегда останавливается, будет чрезвычайно слабым алгоритмом. Причина в том, что вы не можете достичь одного и того же состояния. Если да, вы можете застрять в петле. Представьте себе игру, написанную на этом языке, когда вы ходите по ней, если вы дважды наступаете на какую-нибудь плитку, игра умирает. Даже простая программа, которая получает два числа и печатает сумму, а затем повторять, не может быть записана.
Наконец, возможно, наименее глупым из тех, кто всегда останавливает языки, будет тот, который похож на наши нормальные языки, но просто убивает программу после, скажем, 7 дней.
Это сложный вопрос, так как это зависит от того, что такое определение языка программирования. Одно из возможных определений требует, чтобы было возможно смоделировать любую машину Тьюринга с использованием этого языка (игнорируя практические ограничения, вызванные конечной памятью реальных машин). Если ваше определение включает это требование или его эквивалент, тогда ответ будет отрицательным, так как существуют машины Тьюринга, которые не останавливаются на некоторых входах.
Однако существуют ограниченные компьютерные языки, которые могли бы разумно назвать языки программирования (игнорируя требование, о котором говорилось выше), по крайней мере в принципе (я не знаю, действительно ли они были реализованы). Один из таких языков я называю языком for-language: он поддерживает прямолинейные программы, предложения if-then-else и ограниченные циклы формы
for i = E1 to E2 step E3
... code ...
end for
в котором переменная индукции i
не может быть назначена (и где не удается сформировать указатель на i
). Причина, по которой такой язык может выражать только завершающие программы, заключается в том, что существует максимальное количество итераций, которые может принимать каждый цикл, известный в начале цикла.
Довольно много программ могут быть написаны с использованием языка, подобного языку, но есть некоторые вычислительные проблемы, которых не могло быть. Известный пример, я считаю, вычисляет функцию Акермана.