计算列表中元素的数量:做作是如何工作的

Counting the number of elements in a list: how affectation works

我正在研究一个包含计算列表元素数量的 Prolog 问题:

count([], 0).
count([H|T], N) :-
    count(T, X),
    N is X+1,
    N > 0.

我能理解为什么要这样写,但我不明白为什么我们不能用 X is N-1 ?[=11 替换 N is X+1 =]

非常感谢!

你的问题很有道理,+1。

这个看似随意的选择的原因是 (is)/2 是一个相对低级的谓词,只适用于非常特殊的情况,只能从程序上理解,而不是从声明上理解。因此,(is)/2 对于初学者来说非常难以理解,最好避免使用,因为它破坏了我们在使用 Prolog 时想要享受的许多关系属性。

声明式解决方案是使用约束,在这里您可以完全按照您说的去做。对于整数关系,只需将 (is)/2 替换为 (#=)/2 即可享受您直观期望的关系属性。

例如,使用 GNU Prolog:

count([], 0).
count([_|Ls], N) :-
        count(Ls, X),
        X #= N - 1,
        N #> 0.

在 SICStus Prolog 和 SWI 等其他系统中,您目前仍需要为此使用 library(clpfd)。此外,我强烈建议为这个关系使用一个更具声明性的名称,明确哪个参数表示什么:

:- use_module(library(clpfd)).

list_length([], 0).
list_length([_|Ls], N) :-
        list_length(Ls, X),
        X #= N - 1,
        N #> 0.

示例查询:

?- list_length([_,_,_], N).
N = 3.

?- list_length(Ls, 2).
Ls = [_G602, _G605] .

我把改进这个谓词的终止属性作为一个简单的练习。