Prolog 将列表的所有元素相乘
Prolog multiply all elements of a list
我想在 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) 时。我得到的是 false 而不是 Product = 0。
请帮忙。
您的问题是 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),而 对 SWI-Prolog(多线程)有效, 64 位,版本 7.3.11)。适用于每个版本的解决方案如下:
prod_list([],0).
prod_list([H|T], Product) :- product_of_list([H|T], Product).
感谢 user474491 发现这一点。
Renzo 的回答很完美。当我看到你的问题时,我只是想到了列表的功能处理。您可以拥有它们以备不时之需。如果定义函数乘法:
mul(V1,V2,R) :- R is V1*V2;
然后你可以在它的任何变体中使用 foldl:
?- foldl(mul, [1,2,10], 1, R).
R = 20 .
fold
是一个传统的函数式计算函数,它应用了一个累积时间结果的函数。
我想在 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) 时。我得到的是 false 而不是 Product = 0。
请帮忙。
您的问题是 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),而 对 SWI-Prolog(多线程)有效, 64 位,版本 7.3.11)。适用于每个版本的解决方案如下:
prod_list([],0).
prod_list([H|T], Product) :- product_of_list([H|T], Product).
感谢 user474491 发现这一点。
Renzo 的回答很完美。当我看到你的问题时,我只是想到了列表的功能处理。您可以拥有它们以备不时之需。如果定义函数乘法:
mul(V1,V2,R) :- R is V1*V2;
然后你可以在它的任何变体中使用 foldl:
?- foldl(mul, [1,2,10], 1, R).
R = 20 .
fold
是一个传统的函数式计算函数,它应用了一个累积时间结果的函数。