Prolog在实施反向列表时不会停止

Prolog not halting when implementing reverse list

这是我的实现:

popped_last_el([], [_]).
popped_last_el([F | R], [F | X]) :- popped_last_el(R, X).

last_el(X, [X]).
last_el(X, [_ | L]) :- last_el(X, L).

reverse_list([], []).
reverse_list([F | R], L2) :- last_el(F, L2), popped_last_el(L, L2), reverse_list(R, L).

当我查询 reverse_list([a, b], X) 时,它按预期输出 X = [b, a]。但是当我使用 ; 寻求另一个解决方案时,prolog 会无限期地运行。为什么?

Why?

这里有一个来解释为什么程序还是循环。您的程序中只有这个非常小的部分 对 non-termination 负责。您必须在该部分修复 某些内容 才能使 non-termination 消失。

last_el(X, [X]) :- false.
last_el(X, [_ | L]) :- last_el(X, L), false.

reverse_list([], []) :- false.
reverse_list([F | R], L2) :-
   last_el(F, L2), false,
   popped_last_el(L, L2),
   reverse_list(R, L).

?- reverse_list([a, b], X), false.
   loops.

从这里你可以看出failure-slice:

L2 需要知道 ('instantiated') 才能使 last_el/2 终止。但事实并非如此。