Prolog将列表中的所有元素相乘

时间:2015-11-29 07:12:18

标签: prolog logic-programming

我想在Prolog中定义一个谓词,prod_list / 2将列表的每个元素相乘。我有空列表的问题希望产品应该为零,而我得到假。 我的代码是

prod_list([H], H).
prod_list([H|T], Product) :- prod_list(T, Rest), 
                            Product is H * Rest.

我得到的结果是 prod_list([4,3],产品)。 - >产品= 12 但是当我做prod_list([],Product)时。我得到假而不是产品= 0.

请帮忙。

2 个答案:

答案 0 :(得分:5)

您的问题是 no 子句与空列表匹配。实际上你有一个递归子句:

prod_list([H|T], Product) :- prod_list(T, Rest), 
                        Product is H * Rest.

但当列表中只有一个元素时,它的递归终止:

prod_list([H], H).

因此,在任何情况下,空列表[]都不会被一个子句匹配,因此答案是false(不匹配)。

要解决您的问题,您需要为空列表包含一个显式子句:

prod_list([],0).
prod_list([H],H).
prod_list([H|T], Product) :- prod_list(T, Rest), Product is H * Rest.

考虑到空列表的产品应该(正确地)以这种方式定义,可以找到不同的解决方案:

product_of_list([], 1).
product_of_list([H|T], Product) :- product_of_list(T, Rest), Product is H * Rest

然后您可以添加prod_list的“特殊”定义:

prod_list([],0).
prod_list(List, Product) :- product_of_list(List, Product).

修改

最后一个解决方案不适用于Prolog的某些交互式版本(例如Swish on-line),而 适用于SWI-Prolog(多线程,64位,版本) 7.3.11)。适用于每个版本的解决方案如下:

prod_list([],0).
prod_list([H|T], Product) :- product_of_list([H|T], Product).

感谢user474491发现这一点。

答案 1 :(得分:3)

伦佐的答案是完美的。当我看到你的问题时,我只想到列表的功能处理。你可以拥有它们以防万一你需要它们。如果定义函数乘法:

mul(V1,V2,R) :- R is V1*V2;

然后您可以在其任何变体中使用foldl:

?- foldl(mul, [1,2,10], 1, R).
R = 20 .

fold是一个传统的函数计算函数,它应用一个累加时间结果的函数。