列表中元素的总和

时间:2016-10-21 06:08:47

标签: prolog

我不得不说有一个类似的排队Sum of elements in list in Prolog needs little explanation,但仍让我感到困惑。

以下是需要解释的解决方案。

 sum([H],H).
 sum([H|T],R):-sum(T,P),R is H + P.

让我们说总和([1,2,3],R)。

 sum([1,2,3],R)
    sum([2,3],<unknown-1>)
      sum([3],<unknown-2>)

那么它将实现事实总和([H],H)? 我把这个变量写成sum([H],H),这个案例的唯一输出是3, 这意味着在未知-2中这里是3,为什么?

只是prolog的初学者,任何答案都会非常感激。

1 个答案:

答案 0 :(得分:5)

答案简短:统一

当在谓词子句的范围内,变量名称出现多次时,所有出现的内容都将统一。统一的谓词是=/2,并且被声明为运算符,因此=(A, A)A = A表示相同。更重要的是,这个:

=(Term, Term).

=/2定义(请参阅the documentation!)

在您的示例中,您有一个条款说:

sum([H], H).

这意味着:

  

sum/2的第一个参数是一个只包含一个元素的列表时,sum/2的第二个参数就是该元素。

因为术语统一在Prolog中是如此基本的操作,通常没有明确说明,例如:

  

sum/2的第一个参数是一个只有一个元素的列表时,该元素和sum/2的第二个参数相互统一。

至少在SWI-Prolog文档中,如果涉及统一,通常用&#34来表示; X是Y&#34;代替&#34; X和Y统一&#34;。例如,请参阅the documentation of min_member/2

  

min_member MinList)。

     

如果Min是标准条款顺序中的最小成员,则为真。如果List为空,则失败。

它没有明确告诉您使用了统一,并且由此产生以下行为:

?- min_member(3, [1,2,X]).
X = 3.

我曾经asked a question about this因为我发现它太混乱了。

顺便说一句,根据您当前对sum/2的定义,由于统一的工作方式,您也会感到惊讶。看:

?- sum([1.5, 2.5], Sum).
Sum = 4.0 ; % unnecessary choice point but at least correct
false.

?- sum([1.5, 2.5], 4).
false. % Oops!

SWI-Prolog library implementation遇到同样的问题:

?- sum_list([1.5, 2.5], Sum).
Sum = 4.0. % no choice point, at least

?- sum_list([1.5, 2.5], 4).
false. % Oops!

解决方法是首先将第二个参数保留为自由变量,然后使用=:=/2,它进行算术比较

?- sum_list([1.5, 2.5], Sum), Sum =:= 4.
Sum = 4.0.

您也可以使用sum/2的定义来执行此操作。