Sam4246
Sam4246

Reputation: 13

How to reverse a list and join two lists together in prolog

I need to write a program in prolog that accepts a list, reverses that list and the appends that to the end of the original list.

Example: list_rList([1,2,3],X)
X = [1,2,3,3,2,1]

So far I have been able to reverse the list, but I can manage to append the reverse list to the original list.

Here is what I have:

list_rList([],[]).  
list_rList([H|T],R):-  list_rList(T,RevT),  append(RevT,[H],R).

Upvotes: 1

Views: 717

Answers (2)

Fatalize
Fatalize

Reputation: 3543

Here is a solution which will work correctly in all directions:

list_rList(L, T) :-
    list_rList(L, [], T).

list_rList([], A, A).
list_rList([H|T], C, [H|T2]) :-
    list_rList(T, [H|C], T2).

The second argument will accumulate the reversed list, and the third one will accumulate the result: each element of the original list is appended at the beginning of that third argument, and its tail is the second argument once we have emptied the first list.

Some example queries:

?- list_rList([1,2,3],Z).            % What you asked
Z = [1, 2, 3, 3, 2, 1].

?- list_rList([1|T],Z).              % With a variable tail
T = [],
Z = [1, 1] ;
T = [_G1659],
Z = [1, _G1659, _G1659, 1] ;
T = [_G1659, _G1668],
Z = [1, _G1659, _G1668, _G1668, _G1659, 1]
…

?- list_rList(Z,[1,2,3,3,2,1]).      % The original list from the result
Z = [1, 2, 3] ;
false.

?- list_rList(Z,[1,2,3,3,2]).        % Check that a list can be the result of this predicate
false.

?- list_rList(Z,[1,2,3,X,Y,3,2,1]).  % With variable elements in the result
Z = [1, 2, 3, Y],
X = Y ;
false.

?- list_rList(L,Z).                  % With completely free arguments
L = Z, Z = [] ;
L = [_G1623],
Z = [_G1623, _G1623] ;
L = [_G1623, _G1632],
Z = [_G1623, _G1632, _G1632, _G1623] ;
L = [_G1623, _G1632, _G1641],
Z = [_G1623, _G1632, _G1641, _G1641, _G1632, _G1623] ;
L = [_G1623, _G1632, _G1641, _G1650],
Z = [_G1623, _G1632, _G1641, _G1650, _G1650, _G1641, _G1632, _G1623]
…

Upvotes: 1

ewcz
ewcz

Reputation: 13087

you could do something like this:

accRev([H|T],A,L,R) :-  accRev(T,[H|A],L,R).
accRev([],A,L,R) :- append(L,A,R).

list_rList(L,R) :- accRev(L,[],L,R).

Here, first the list is reversed using an accumulator (the second argument of accRev) and once this is finished, the original list (which is kept in the third argument of accRev) is prepended.

Upvotes: 0

Related Questions