I want to define a predicate in Prolog, prod_list/2 that multiplies every element of a list. I'm having problem with the empty list wish the product should be zero, instead i get false. My code is
prod_list([H], H).
prod_list([H|T], Product) :- prod_list(T, Rest),
Product is H * Rest.
The results I get are prod_list([4,3],Product). -> Product = 12 but when I do prod_list([], Product). I get false instead of Product = 0.
Please help.
Your problem is that no clause matches the empty list. In fact you have a recursive clause:
prod_list([H|T], Product) :- prod_list(T, Rest),
Product is H * Rest.
but its recursion terminates when there is only an element in the list:
prod_list([H], H).
So, in no case the empty list []
is matched by a clause, and for this reason, the answer is false
(no match available).
To solve your problem you need to include an explicit clause for the empty list:
prod_list([],0).
prod_list([H],H).
prod_list([H|T], Product) :- prod_list(T, Rest), Product is H * Rest.
A different solution could be found considering that the product of an empty list should be (correctly) defined in this way:
product_of_list([], 1).
product_of_list([H|T], Product) :- product_of_list(T, Rest), Product is H * Rest
then you could add your “special” definition of prod_list
:
prod_list([],0).
prod_list(List, Product) :- product_of_list(List, Product).
Edit
The last solution does not work for some interactive versions of Prolog (for instance Swish on-line), while it does work for SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.11). A solutions that should work for every version is the following:
prod_list([],0).
prod_list([H|T], Product) :- product_of_list([H|T], Product).
Thanks to user474491 for discovering this.