Если я правильно интерпретирую ваш вопрос, вы хотите заменить элемент по заданному индексу в списке:
% replace_at( In, At, With, Replaced )
replace_at( [], _I, _N, []).
replace_at( [_|T], I, N, [N|T]) :- I =:= 0.
replace_at( [H|T], I, N, [H|T2]) :- I > 0, I2 is I-1,
replace_at( T, I2, N, T2).
Тестирование:
?- Shop = [["Bread","Donuts","Cookies"],["Beer","Cider","Juice"],["Ham","Raw Meat","Sausage"]],
replace_at( Shop, 1, ["Beer", "Milk", "Juice"], NewShop), nl,
maplist( writeln, Shop), nl, maplist( writeln, NewShop), nl.
[Bread,Donuts,Cookies]
[Beer,Cider,Juice]
[Ham,Raw Meat,Sausage]
[Bread,Donuts,Cookies]
[Beer,Milk,Juice]
[Ham,Raw Meat,Sausage]
Shop = [["Bread", "Donuts", "Cookies"], ["Beer", "Cider", "Juice"], ["Ham", "Raw Meat", "Sausage"]],
NewShop = [["Bread", "Donuts", "Cookies"], ["Beer", "Milk", "Juice"], ["Ham", "Raw Meat", "Sausage"]] ;
false.
Дает вывод что вы хотели.
То, что элементы списка сами по себе являются списками, здесь несущественно.
Если, с другой стороны, вы когда-нибудь захотите использовать два индекса в вызов, чтобы указать, что J
-й элемент в I
-ом списке (на основе 0) в списке списков должен быть заменен, вы можете просто использовать вышеупомянутый предикат, дважды, чтобы выполнить sh что:
% replace_at2d( In, AtLine, AtWord, With, Replaced )
replace_at2d( LL, I, J, W, LL2 ) :-
nth0( I, LL, L), % I-th line
replace_at( L, J, W, L2 ), % J-th word
replace_at( LL, I, L2, LL2 ).
Тестирование:
?- Shop = [["Bread","Donuts","Cookies"],["Beer","Cider","Juice"],["Ham","Raw Meat","Sausage"]],
replace_at2d( Shop, 1, 1, "Milk", NewShop), nl,
maplist( writeln, Shop), nl, maplist( writeln, NewShop), nl.
[Bread,Donuts,Cookies]
[Beer,Cider,Juice]
[Ham,Raw Meat,Sausage]
[Bread,Donuts,Cookies]
[Beer,Milk,Juice]
[Ham,Raw Meat,Sausage]
Shop = [["Bread", "Donuts", "Cookies"], ["Beer", "Cider", "Juice"], ["Ham", "Raw Meat", "Sausage"]],
NewShop = [["Bread", "Donuts", "Cookies"], ["Beer", "Milk", "Juice"], ["Ham", "Raw Meat", "Sausage"]] ;
false.