我想在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.
请帮忙。
答案 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
是一个传统的函数计算函数,它应用一个累加时间结果的函数。