Le problème est qu'une fois que vous trouvez une liste imbriquée, vous oubliez ce qui est derrière cette liste imbriquée. Au lieu de cela, après avoir récuré avec le nid imbriqué, continuez simplement comme avant. Ainsi, vous devez changer la dernière clause comme suit:
subs(X,Y,[H|L1],[H2|L2]):- X\=H, H=[_|_], subs(X,Y,H,H2), subs(X, Y, L1, L2).
En dehors de cela, il y a deux façons dont vous pouvez améliorer le code:
- Utilisez cuts (
!/0
) à arrêter de faire marche arrière. De cette façon, vous n'avez pas à vous répéter.
- Vous pouvez utiliser
is_list/1
pour tester si un argument est une liste.
- Il est correct d'utiliser plus d'espaces. Vraiment.
Ainsi, une solution alternative est (maintenant à l'aide \+/1
au lieu de not/1
):
subs(_, _, [], []).
subs(X, Y, [X|T1], [Y|T2]) :- subs(X, Y, T1, T2), !.
subs(X, Y, [H|T1], [H|T2]) :- \+ is_list(H), subs(X, Y, T1, T2), !.
subs(X, Y, [H1|T1], [H2|T2]) :- subs(X, Y, H1, H2), subs(X, Y, T1, T2).
Démonstration:
?- subs(a, b, [a, [a, [d, f, a]], a, b, a, [g]], Z).
Z = [b, [b, [d, f, b]], b, b, b, [g]].
Cela se révèle être homewo rk: http://www.cs.toronto.edu/~yilan/324f09/324f09a4.pdf La prochaine fois, ** s'il vous plaît ** marquer comme tel! – Stephan202