1
sum([],0).
sum([H|T],S) :- sum(T,X),S is X+H.

mean([],0).
mean(L,M) :- sum(L,S),length(L,L1),M is S/L1.
:-arithmetic_function(mean/1).
when i try 
?- mean([1,2,3,4],X).

它回复

X= 2.5 
Yes 

现在我想使用

?- X is mean ([1,2,3,4]. 

但它与

Type error: ERROR: '.'/2: Type error: `[]' expected, found `[2, 3, 4]' ("x" must hold one character) 

如何将算术函数与列表一起使用?

4

1 回答 1

3

虽然您的代码看起来在正确的轨道上,但不幸的是,似乎不能将任意长度的数字列表用作定义为arithmetic_functions 的函数的参数(参数),例如您的参数 to mean/1

问题似乎与在 SWI-Prolog./2中本身被认为是这种上下文中的算术类型这一事实有关。

解释:

考虑:

?- X is 1 + 2 * 3.
X = 7. 

因为算术运算符*优先于+,这实际上是:

?- X is (1 + (2 * 3)).
X = 7. 

此外,+and*是二进制中缀运算符,否则可以这样写:

?- X is '+'(1, '*'(2, 3)).
X = 7. 

请注意,在这里,SWI-Prolog 实际上是*先评估表达式树“由内而外”,然后将结果应用于+表达式。考虑到这一点,现在考虑您的示例:

?- X is mean([1,2,3,4]).

SWI-Prolog 实际解释的其实是:

?- X is mean('.'(1,[2,3,4])).

现在,因为'.'/2是算术类型,SWI-Prolog 首先评估这个表达式(如*上面的示例),但类型检查表明它不是所需的模式.(+Int,[]),即长度为 1 的列表包含一个整数(参见文档在上面的链接后面)。由于[]不等于[2,3,4],因此会引发您报告的类型错误。

您也可以考虑尝试以下方法:

?- X is mean([1]).

SWI-Prolog 实际解释的其实是:

?- X is mean('.'(1,[])).

现在,虽然这是类型 pattern 的一个有效实例,但根据这种算术类型的语义.(+Int,[]),它被评估*(与上面所示的评估方式大致相同)给出 。1然后将该值1绑定到 的实现的第一个输入参数,mean/2否则您希望成为输入列表。

于 2011-01-05T11:15:02.703 回答