定义sum(X, N) 谓词,当N 是列表X 中的整数之和时为真。
您想要计算列表元素的总和。问题的最简单实例是什么?当列表为空时,其元素之和为0。我们如何分解更大的列表来处理简单的情况?我们可以删除列表的第一个元素,计算剩余列表的总和,然后将第一个元素添加到结果中。
这个方法可以用下面的代码来实现:
% Simple case: Sum of the empty list
sum([], 0).
% Recursive case: Split list into first element X and remaining list XS
sum([X|XS], N) :- sum(XS, M), N is M + X.
用法:
?- sum([1,2,3],6).
true.
?- sum([1,2,3],X).
X = 6.
is 运算符对其右侧 (reference) 进行算术评估,而不是将 M + X 视为字面术语。如果您使用= 而不是is,则M + X 将被视为字面术语。然后你会得到以下输出:
?- sum([1,2,3],6).
false.
?- sum([1,2,3],0+3+2+1).
true.
所以对于 Prolog,6 和 0+3+2+1 是不同的术语,直到您强制执行 is 完成的算术评估。
2) 定义 avg (X, N) 谓词,计算列表 X 的所有元素的算术平均值,其中 N 是元素的数量。
这是不可能的。如果X 是列表,N 是元素数,那么谓词无法输出平均值(除非您将打印平均值算作副作用,我认为您不需要)。要解决此问题,请添加另一个表示平均值的参数 A:avg(X, N, A)。
我们可以通过将列表的总和除以列表的长度来计算平均值:
avg(X, N, A) :- sum(X, S), length(X, N), A is S / N.
用法:
?- avg([1,2,3],3,2).
true.
?- avg([1,2,3,4],N,X).
N = 4,
X = 2.5.
3) 定义名为 count(X, Y, N) 的谓词,如果列表 Y 包含 N 个元素实例 X,则该谓词为真。
我了解您希望 N 是数字 X 在列表 Y 中出现的次数。我们可以再次将其分解为一个简单案例,然后尝试将一般案例分解为更小的步骤,直到我们到达简单案例。
对于一个空列表,我们知道X 在该列表中出现零次。对于非空列表,我们可以删除第一个元素并检查X 在剩余列表中出现的频率。如果第一个元素等于X,则X 的总出现次数是剩余列表中出现次数的一加。如果第一个元素不等于X,则X 出现的总次数等于剩余列表中出现的次数。
这个方法可以用下面的代码来实现:
% Simple case: The list is empty.
count(_, [], 0).
% Recursive case: First element is equal to X
count(X, [X|YS], N) :- count(X, YS, M), N is M + 1, !.
% Recursive case: First element is unequal to X
count(X, [Y|YS], N) :- X \= Y, count(X, YS, N).
我们将_ 用于我们不关心的变量。我们也可以写成X 而不是_,但是Prolog 会给我们一个未使用变量的警告。
用法:
?- count(1, [1,1,2,3], N).
N = 2.
?- count(2, [1,1,2,3], N).
N = 1.