【发布时间】:2021-10-09 06:27:49
【问题描述】:
以下 Prolog 程序定义了一个谓词 rev/2 用于反转传入第一个参数的列表,从而导致传入第二个参数的列表:
rev([], []).
rev([XH|XT], Y) :-
rev(XT, Z),
append(Z, [XH], Y).
append([], Y, Y).
append([XH|XT], Y, [XH|ZT]) :-
append(XT, Y, ZT).
以下 Prolog 程序是 rev/2 的替代实现:
rev(X, Y) :-
revappend(X, [], Y).
revappend([], Y, Y).
revappend([XH|XT], Y, Z) :-
revappend(XT, [XH|Y], Z).
在这种参数模式下,两个程序都按预期工作:
?- rev([a, b, c], Y).
Y = [c, b, a]
; false.
但是这两个程序在这种参数模式下都耗尽了查询资源:
?- rev(X, [a, b, c]).
X = [c, b, a]
;
Time limit exceeded
问题:
- 如何修复这两个程序?
- 两个程序是否等效?
【问题讨论】:
-
他们都提供了第一个答案,但他们陷入了第二个无限计算。尝试执行:
trace, rev(X, [a, b, c]).,你会明白为什么两者都没有终止 -
@damianodamiano 随意纠正答案。
-
@Maggyero 我猜这是弗洛伊德的失误,
right与write。我拥有的不仅仅是我的份额。 -
@GuyCoder 哎呀,我猜你在写。
标签: list prolog reverse termination failure-slice