Search code examples
prologlogic-programming

Prolog multiply all elements of a list


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.


Solution

  • 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.