Append a Star after every element of a given list in prolog

Viewed 61

In this predicate listStar(L,R), I want to append a * after every element of a given list e.g.:

   ?- listStar([1,2,3,4] , R).                       
R = [1,*,2,*,3,*,4,*]
listStar([],[]).
listStar([X|Xs],[X,Z|Zs]) :- Z is ['*'],listStar(Xs,Zs).

After the execution of this code i got this result:

R = [1, 42, 2, 42, 3, 42, 4, 42].

Any help !

2 Answers
elems_star([], []).
elems_star([H|T], [H, '*'|S]) :-
    elems_star(T, S).

Result:

?- elems_star([1, 2, 3, 4], L).
L = [1,*,2,*,3,*,4,*].

Whenever you are using Prolog to describe lists it's worthwhile to consider using DCGs for the task, since they yield easily readable code:

starified([]) -->           % if the argument list is empty
    [].                     % so is the starified list
starified([X|Xs]) -->       % if the argument list starts with an X followed by some tail Xs
    [X,*],                  % the starified list contains an X followed by a star
    starified(Xs).          % and the tail is starified as well
   
list_starified(L,S) :-
    phrase(starified(L),S). % using phrase/2 to call the DCG starified//1

The predicate list_starified/2 can then be the used to describe a list with added stars:

   ?- list_starified([1,2,3,4],S). % What's the corresponding starified list to [1,2,3,4]?
S = [1,*,2,*,3,*,4,*]

Or to remove the stars from a starified list:

   ?- list_starified(L,[1,*,2,*,3,*,4,*]). % What's the corresponding non-starified list to [1,*,2,*,3,*,4,*]?
L = [1,2,3,4] ? ;
no

Or to check if the second list is starified as described above, by writing a _ instead of a variable-name for the first argument:

   ?- list_starified(_,[1,*,2,*,3,*,4,*]). % Is [1,*,2,*,3,*,4,*] a proper starified list?
yes
   ?- list_starified(_,[1,*,2,*,3,*,4]).   % Is [1,*,2,*,3,*,4] a proper starified list?
no

Or it can be used to generate pairs of lists and their corresponding counterparts with added stars:

   ?- list_starified(L,S). % what lists and corresponding starified list are there? 
L = S = [] ? ;             % the empty list
L = [_A],                  % the one-element list
S = [_A,*] ? ;
L = [_A,_B],               % the two-element list
S = [_A,*,_B,*] ? ;
L = [_A,_B,_C],            % the three-element list
S = [_A,*,_B,*,_C,*] ?; 
.
.
.
Related