Вы хотите применить некоторую операцию к соответствующим элементам двух списков. Эта операция говорит о списках сама. Легко запутаться с вложенными уровнями списков, поэтому давайте попробуем думать , а не в этих терминах. Вместо этого сначала определите предикат, который выполняет расширение списка one :
element_list_extended(Element, List, Extended) :-
append(List, [Element], Extended).
Это ведет себя следующим образом, используя случаи из вашего примера:
?- element_list_extended(a, [b, c], Extended).
Extended = [b, c, a].
?- element_list_extended(a, List, [x, y, z, a]).
List = [x, y, z] ;
false.
Хорошо выглядит. Все, что нам нужно сделать, это применить эту операцию к соответствующим элементам двух списков:
extends(_Element, [], []).
extends(Element, [Xs | Xss], [Ys | Yss]) :-
element_list_extended(Element, Xs, Ys),
extends(Element, Xss, Yss).
И это работает:
?- extends(a, [[b,c], [d,e,f], [x,y,z]], Y).
Y = [[b, c, a], [d, e, f, a], [x, y, z, a]] ;
false.
Ключом к тому, чтобы заставить его работать, было разложить проблему на две части и решить эти более простые части отдельно.
Теперь, если нам нравится, поскольку определение element_list_extended/3
представляет собой единое предложение, содержащее одну цель, мы можем решить обойтись без него и включить его определение в extends/3
:
extends(_Element, [], []).
extends(Element, [Xs | Xss], [Ys | Yss]) :-
append(Xs, [Element], Ys),
extends(Element, Xss, Yss).
Как видите, вы были совсем близко! У вас просто были лишние скобки, потому что вы запутались во вложении списков. Именно здесь помогает разложение проблемы.
(Как сказал другой ответ, в SWI-Prolog есть несколько полезных библиотек, которые позволяют вам выразить даже это в еще более коротком коде.)