我正在处理Prolog问题,包括计算列表元素的数量:
count([], 0).
count([H|T], N) :-
count(T, X),
N is X+1,
N > 0.
我能理解为什么会这样写,但我不明白为什么我们不能用 X是N-1 代替N是X + 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] .
我将这个谓词的终止属性改进为一个简单的练习。