在Prolog中,是统一X = [1|X]
一种获得无限列表的明智方法?
这取决于您是否认为生成无限列表是明智的。在 ISO-Prolog 中,统一如下X = [1|X]
受到发生检查 (STO) 的影响,因此未定义。也就是说,符合标准的程序一定不能执行这样的目标。为了避免这种情况发生,有unify_with_occurs_check/2
, subsumes_term/2
。为了防止接口接收无限项,有acyclic_term/1
.
所有当前的实现都终止于X = [1|X]
。 GNU Prolog 也终止:
| ?- X = [1|X], acyclic_term(X).
no
但对于更复杂的情况,需要合理的树统一。将此与 Haskell 进行比较,其中repeat 1 == repeat 1
causes ghci
冻结。
至于在常规 Prolog 程序中使用有理树,一开始很有趣,但扩展得不太好。例如,在 20 世纪 80 年代初的一段时间内,人们相信语法将使用有理树来实现。唉,人们对 DCG 已经足够满意了。
这没有离开研究的原因之一是,Prolog 程序员假设存在的许多概念对于有理树来说并不存在。以词典术语排序为例,它对于理性树没有扩展。也就是说,存在无法使用标准术语顺序进行比较的理性树。 (实际上,这意味着您会得到准随机结果。)这意味着您无法生成包含此类术语的排序列表。这又意味着许多内置函数喜欢bagof/3
不再可靠地使用无限项。
对于您的示例查询,请考虑以下定义:
memberd(X, [X|_Xs]).
memberd(E, [X|Xs]) :-
dif(E,X),
memberd(E, Xs).
?- X = 1, Xs=[1|Xs], memberd(X,Xs).
X = 1, Xs = [1|Xs]
; false.
所以有时有一些简单的方法可以避免非终止。但大多数情况下都没有。