Home > Back-end >  Add one element at the end of every sub list of a list
Add one element at the end of every sub list of a list

Time:12-04

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?

CodePudding user response:

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.

CodePudding user response:

Here it is, a simple recursive solution with append/3.

add_all(_,[],[]).
add_all(El,[(V=L)|T],[(V=L1)|T1]):-
    append(L,[El],L1),
    add_all(El,T,T1).

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

If you want to remove the false result, place a cut (!) in the body of the first rule.

  • Related