Jon*_*ner 6 prolog swi-prolog iso-prolog
最近进入Prolog我已经将它用于一些简单的任务,并开始怀疑在forall循环中使用成员,如下面的简单示例中的那个:
forall(member(A,[1,2,3,4]), print(A)).
Run Code Online (Sandbox Code Playgroud)
如果您执行类似这样的操作,那么forall每次调用时都会以相同的顺序处理列表中的元素吗?是否必须通过执行以下操作来强制执行:
A = [1,2,3,4], sort(A, B), forall(member(C,B), print(C)).
Run Code Online (Sandbox Code Playgroud)
从我最初做的小研究中我猜测它归结为member/2的行为,但SWI-Prolog网站上的功能文档非常简短.然而它确实提到了关于成员/ 2的确定性,这给了我一个暗示,我可能正在说道,它总是以相同的顺序提取元素,尽管我很不确定.
有人能给我任何保证或解释吗?
Prolog 中的非确定性只是指谓词可能具有多个解决方案。显然,member/2
就是这样一个谓词。这并不意味着您必须担心您的计算变得不可预测。Prolog 有一个明确定义的计算规则,本质上是说以深度优先、从左到右的方式探索替代解决方案。因此,您的目标将按照预期顺序 1、2、3、4member(X,[1,2,3,4])
生成解决方案。X
对列表 [1,2,3,4] 进行排序不会产生任何影响,因为它已经排序了(根据 Prolog 的标准术语顺序)。
需要注意的是forall/2
:一些 Prolog 定义了这一点,但它可能没有你想象的那么有用,因为它并不是真正的“循环”。您可以在示例中使用它,因为您在每次迭代中仅执行打印副作用。对于大多数其他目的,您应该熟悉递归模式,例如
print_list([]).
print_list([X|Xs]) :- print(X), print_list(Xs).
Run Code Online (Sandbox Code Playgroud)