计算列表中元素的数量:影响的工作原理

时间:2016-02-25 16:37:22

标签: prolog clpfd

我正在处理Prolog问题,包括计算列表元素的数量:

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

我能理解为什么会这样写,但我不明白为什么我们不能用 X是N-1 代替N是X + 1?

非常感谢!

1 个答案:

答案 0 :(得分:5)

你的问题非常合理,+ 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] .

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