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.