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)
如何将算术函数与列表一起使用?
答案 0 :(得分:3)
虽然您的代码看起来像是在正确的轨道上,但不幸的是,似乎任意长度的数字列表不能用作作为参数(参数)定义为arithmetic_function
的函数s,例如mean/1
的参数。
问题似乎与此情况下的in SWI-Prolog, ./2
is itself considered to be an arithmetic type有关。
<强>解释强>
考虑一下:
?- X is 1 + 2 * 3.
X = 7.
因为算术运算符*
优先于+
,所以实际上是这样的:
?- X is (1 + (2 * 3)).
X = 7.
此外,+
和*
是二进制中缀运算符,否则可以这样写:
?- 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首先计算此表达式(如上例中的*
),但类型检查显示它不是所需的模式{ {1}},即包含整数的长度为1的列表(请参阅上面链接背后的文档)。由于.(+Int,[])
不等于[]
,因此会引发您报告的类型错误。
您也可以考虑尝试以下方法:
[2,3,4]
SWI-Prolog实际上解释的是:
?- X is mean([1]).
现在,虽然这是类型模式?- X is mean('.'(1,[])).
的有效实例,但已评估(与上面显示的.(+Int,[])
的评估方式大致相同)根据此算术类型的语义,给出*
。然后将值1
绑定到1
实现的第一个输入参数,否则您将成为输入列表。