I\'ve developed a predicate which replaces the value of the index Index
of a list List
with Value
and creates a new updated list New
Your problem statement is a bit unclear.
From your examples, it would appear that what you want to treat a list-of-lists as essentially a 2-D array, and replace a single cell within that array. If so, this is one way (probably non-optimal) to do that:
%
% replace a single cell in a list-of-lists
% - the source list-of-lists is L
% - The cell to be replaced is indicated with a row offset (X)
% and a column offset within the row (Y)
% - The replacement value is Z
% - the transformed list-of-lists (result) is R
%
replace( L , X , Y , Z , R ) :-
append(RowPfx,[Row|RowSfx],L), % decompose the list-of-lists into a prefix, a list and a suffix
length(RowPfx,X) , % check the prefix length: do we have the desired list?
append(ColPfx,[_|ColSfx],Row) , % decompose that row into a prefix, a column and a suffix
length(ColPfx,Y) , % check the prefix length: do we have the desired column?
append(ColPfx,[Z|ColSfx],RowNew) , % if so, replace the column with its new value
append(RowPfx,[RowNew|RowSfx],R) % and assemble the transformed list-of-lists
.
Another way (probably more optimal):
replace( [L|Ls] , 0 , Y , Z , [R|Ls] ) :- % once we find the desired row,
replace_column(L,Y,Z,R) % - we replace specified column, and we're done.
. %
replace( [L|Ls] , X , Y , Z , [L|Rs] ) :- % if we haven't found the desired row yet
X > 0 , % - and the row offset is positive,
X1 is X-1 , % - we decrement the row offset
replace( Ls , X1 , Y , Z , Rs ) % - and recurse down
. %
replace_column( [_|Cs] , 0 , Z , [Z|Cs] ) . % once we find the specified offset, just make the substitution and finish up.
replace_column( [C|Cs] , Y , Z , [C|Rs] ) :- % otherwise,
Y > 0 , % - assuming that the column offset is positive,
Y1 is Y-1 , % - we decrement it
replace_column( Cs , Y1 , Z , Rs ) % - and recurse down.
. %