Puisque vous décrivez des listes, vous pouvez choisir d'utiliser des DCG. Tenez compte des règles suivantes:
x_dup(_X,[]) --> % if the input list is empty
[]. % the output list is empty
x_dup(X,[X|Ys]) --> % if X and the head of the list are equal
[X,X], % X is twice in the output list
x_dup(X,Ys). % the same holds for X and the tail
x_dup(X,[Y|Ys]) --> % if X and the head of the input list
{dif(X,Y)}, % are different
[Y], % the head is once in the output list
x_dup(X,Ys). % the same holds for X and the tail
Si vous ne souhaitez que dupliquer la tête de la liste, vous pouvez définir le prédicat d'appel comme ceci:
dups([],[]). % <- only for empty list
dups([X|Xs],L) :-
phrase(x_dup(X,[X|Xs]),L).
La première règle est que pour faire face à la liste vide. Si vous n'avez pas l'intention que votre prédicat couvre ce cas, omettez simplement la première règle. Interrogation avec votre exemple donne le résultat souhaité:
?- dups([a,b,a,a,c,c,c],L).
L = [a,a,b,a,a,a,a,c,c,c] ? ;
no
Vous pouvez définir le prédicat d'appel de telle sorte que vous pouvez dupliquer un élément arbitraire. Dans ce cas, vous avez besoin d'un argument supplémentaire pour spécifier l'élément à dupliquer:
dups(X,L1,L2) :-
phrase(x_dup(X,L1),L2).
Quelques exemples de requêtes:
?- dups(a,[a,b,a,a,c,c,c],L).
L = [a,a,b,a,a,a,a,c,c,c] ? ;
no
?- dups(b,[a,b,a,a,c,c,c],L).
L = [a,b,b,a,a,c,c,c] ? ;
no
?- dups(c,[a,b,a,a,c,c,c],L).
L = [a,b,a,a,c,c,c,c,c,c] ? ;
no
?- dups(d,[a,b,a,a,c,c,c],L).
L = [a,b,a,a,c,c,c]
Seul le premier élément * *? Ou voulez-vous revenir en arrière et générer ainsi une liste pour * chaque * élément? –
Ce que je veux, c'est dupliquer tous les caractères 'a' dans la liste. Par exemple; abaaccc => aabaaaaccc –