Search code examples
prolog

Understanding this implementation of reverse list in prolog


I have written the following small knowledge base for reversing a given list,

reverse_list([],[]).
reverse_list([X|L1], [L2|X]) :-
   reverse_list(L1, L2).

Currently, when executed

reverse_list([a,b,c,d], X).

It produces,

X = [[[[[]|d]|c]|b]|a].

An explanation of why it happens would be much appreciated. And, how can I get around this problem?

I think at last step L2 becomes [] and during back propagation it becomes like that. How can I get the output like , X = [d,c,b,a] using a modification of this approach.

P.S: I am new at Prolog.


Solution

  • To reverse a list you need three parameters :

    reverse_list(L,L1):-reverse_list(L,[],L1).
    reverse_list([],ACC,ACC).
    reverse_list([X|L], ACC,L1):- reverse_list(L,[X|ACC],L1).
    

    First you call reverse_list(L,L1) which calls reverse_list(L,[],L1). where second parameter is working as an accumulator storing all the element in reverse order of your first list. So it calls reverse_list([X|L1], ACC,L). where in the first call ACC (accumulator) is empty list, then you call recursively reverse_list(L1,[X|ACC],L). which is the same thing but you moved X from first list and stored to accumulator. Finally the process stops when the first list is empty and all element are passed to ACC with reverse order and then you unify the third List with ACC.

    As an example: L=[1,2,3],ACC=[],L isn't evaluated. call reverse_list([2,3],[1],L). in the next recursive step call reverse_list([3],[2,1],L). call reverse_list([],[3,2,1],[3,2,1]). last list is unified with ACC=[3,2,1].

    Querying the above example gives:

    ?- reverse_list([1,2,3],L).
    L = [3, 2, 1].