用Prolog定义我的算术函数?

时间:2011-01-02 08:59:35

标签: swi-prolog

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) 

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

1 个答案:

答案 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实现的第一个输入参数,否则您将成为输入列表。