Search code examples
listprolog

Add one element at the end of every sub list of a list


So another prolog question here.

As the title indicated, I tried to add one element on each sublist of a list. But things really don't go well. Here's my code so far:

add_char(Char, Motif, NewM):- append(Motif, [Char], NewM).
add_all(Char, [], _, RE).
add_all(Char, [H|T], Pred, RE):-
    add_char(Char, H, NewH),
    append(Pred, [NewH], RE),
    add_all(Char, T, RE, NewRE).

My code just wanna return the head instead of the whole list as result. like:

?- add_all(h, [(v=[1,2,3]), (i = [5,6,7]), (e = [r,e,w])], [],X).
X = [v=[1, 2, 3, h]] 

What I expect is

X = [v=[1, 2, 3, h],i = [5,6,7,h],e = [r,e,w,h]].

Can anyone help?


Solution

  • Things you are conveniently ignoring:

    Singleton variables: [Char,RE]

    Singleton variables: [NewRE]

    Attend to those warnings, they are there to point out problems.

    Anyway; those things in your list are not exactly sublists; you have a list of terms properly written as =(v,[1,2,3]), so you cannot use append on them until you take them apart ('destructure' them) and get the lists out.

    add_char(Char, (X=Motif), (X=NewM)) :-  % destructures v=[1,2,3]
        append(Motif, [Char], NewM).        % appends to [1,2,3]
    
    
    add_all(_, [], []).                     % stops when [H|T] is empty []
    
    add_all(Char, [H|T], [NewH|Rs]):-       % relates [H|T] and [NewH|NewHs]
        add_char(Char, H, NewH),            % adds this one
        add_all(Char, T, Rs).               % does the rest
    

    It is weird to use = like (v=[1,2,3]) I think v-[1,2,3] is more standard. And SWI Prolog is optimised if you put the [H|T] as the first argument, because stepping over lists is so common, so swap them around if you can.