Я знаю, что можно доказать, что PROLOG является полным по Тьюрингу, создав программу, которая имитирует машину Тьюринга, например:
turing(Tape0, Tape) :-
perform(q0, [], Ls, Tape0, Rs),
reverse(Ls, Ls1),
append(Ls1, Rs, Tape).
perform(qf, Ls, Ls, Rs, Rs) :- !.
perform(Q0, Ls0, Ls, Rs0, Rs) :-
symbol(Rs0, Sym, RsRest),
once(rule(Q0, Sym, Q1, NewSym, Action)),
action(Action, Ls0, Ls1, [NewSym|RsRest], Rs1),
perform(Q1, Ls1, Ls, Rs1, Rs).
symbol([], b, []).
symbol([Sym|Rs], Sym, Rs).
action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs).
action(stay, Ls, Ls, Rs, Rs).
action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs).
left([], [], Rs0, [b|Rs0]).
left([L|Ls], Ls, Rs, [L|Rs]).
Однако мне интересно, какие части языка PROLOG можно было бы убрать (особенно символы функций, перегрузка предложений, рекурсия, объединение) без потери полноты по Тьюрингу. Являются ли сами символы функций Тьюринга завершенными?
Ответы:
Это довольно надежное эмпирическое правило о том, что полнота по Тьюрингу зависит от способности строить ответы или промежуточные значения неограниченного «размера» и от способности циклически повторять или повторять неограниченное количество раз. Если у вас есть эти две вещи, вы, вероятно, обладаете полнотой по Тьюрингу. (Точнее, если вы можете построить арифметику Пеано, то у вас, конечно же, будет полнота по Тьюрингу!)
Давайте пока предположим, что вы уже удалили арифметику. Мы также будем считать , что у вас нет каких - либо не-логические функции , такие как
atom_chars
,assert
и так далее, которые позволяют общие проделки.Если вы удалили функциональные символы, вы не можете создавать ответы или промежуточные элементы неограниченного размера; Вы можете использовать только атомы, которые появляются в программе и запросе. В результате набор всех возможных решений любого запроса является конечным , поэтому выбор наименее фиксированной точки программы / запроса всегда завершится. Datalog (язык запросов к реляционной базе данных, основанный на Prolog) работает по этому принципу.
Точно так же, если вы ограничиваете Пролог только примитивной рекурсией (которая не включает рекурсию как вырожденный случай), то количество рекурсии, которое вы можете сделать, ограничено размером запроса, поэтому все вычисления завершаются. Так что вам нужна общая рекурсия для полноты по Тьюрингу.
И, конечно же, если у вас есть общая рекурсия, вы можете вырезать целый набор функций и сохранить полноту по Тьюрингу, включая общее объединение (достаточно построения и сопоставление с шаблоном верхнего уровня), отрицание и разрез.
источник
Завершение отличного ответа от @Pseudonym и обращение к вашему последнему вопросу: «Являются ли символы функций самим по Тьюрингу завершенными?».
Вы, вероятно, имеете в виду: может ли язык, состоящий только из функциональных символов, быть Turing-Complete?
Ответ - да, подумайте о языках функционального программирования, таких как ML и Haskell.
источник