我是 Prolog 新手,我正在尝试编写一个谓词,其中矩阵如 M = [[_, _, a, ], [, _, _, ], [a, a, a, a], [, _, a, _]], 给出了一个字母和一个坐标,我需要用该字母替换该坐标。
这是我到目前为止所拥有的,但是当它到达替换中的replaceRow时它会失败。我确信有一种更简单的方法可以做到这一点,我真的很感激一些帮助!预先感谢您。
insert(Matrix, Letter, (L, C)):-
insert(Matrix, Letter, (L, C), []).
insert(Matrix, Letter, (L, C), NewMatrix):-
replace(Matrix, L, C, Letter, NewMatrix).
replace(Matrix, L, C, Letter, NewMatrix):-
replace(Matrix, 1, L, C, Letter, [], NewMatrix).
replace([], _, _, _, _, NewMatrix, NewMatrix).
replace([H|T], L2, L, C, Letter, Aux, NewMatrix) :-
(
L2 < L;
L2 > L
->
L2 is L2 + 1,
append(Aux, [H], NewAux),
replace([T], L2, L, C, Letter, NewAux, NewMatrix);
L2 == L,
replaceRow(H, C, Letter, Aux, NewMatrix),
replace([T], L2, L, C, Letter, Aux, NewMatrix)
).
replaceRow(Matrix, C, Letter, Aux, NewMatrix) :-
replaceRow(Matrix, 1 , C, Letter, Aux, NewMatrix).
replaceRow([], _, _, _, NewMatrix, NewMatrix) :- !.
replaceRow([H | T], C2 , C, Letter, Aux, NewMatrix) :-
(
C2 < C;
C2 > C
->
NewC is C2 + 1,
append(Aux, [H], NewAux),
replaceRow(T, NewC, C, Letter, NewAux, NewMatrix);
C2 == C,
NewC is C2 + 1,
append(Aux, [Letter], NewAux),
replaceRow(T, NewC, C, Letter, NewAux, NewMatrix)
).
```
替换列表中的元素:
nth1_replace(I, NewItem, List, OldItem, NewList) :-
% Add start index
nth1_replace_(List, 1, I, NewItem, OldItem, NewList).
nth1_replace_(List, U, I, NewItem, OldItem, R) :-
% Cut, to avoid unwanted choicepoint
( I == U
-> !
; I = U
),
% Unify *after* the cut
List = [OldItem|List0],
R = [NewItem|List0].
nth1_replace_([H|T], U, I, NewItem, OldItem, [H|LU]) :-
% Compare, if possible
( var(I)
-> true
; I > U
),
U1 is U + 1,
nth1_replace_(T, U1, I, NewItem, OldItem, LU).
swi-prolog 中的结果:
% General query
?- nth1_replace(I, E, L, Old, NewL).
I = 1,
L = [Old|_A],
NewL = [E|_A] ;
I = 2,
L = [_A, Old|_B],
NewL = [_A, E|_B] ;
I = 3,
L = [_A, _B, Old|_C],
NewL = [_A, _B, E|_C] ;
% Deterministic
?- nth1_replace(3, r, [a,b,c,d,e,f], Old, NewL).
Old = c,
NewL = [a, b, r, d, e, f].
提示:对于矩阵,您需要调用
nth1_replace
twice。
要通过索引替换元素,您可以使用 length/2 和append/3,如下所示:
replace_nth1(List, N, Old, New, Replaced) :-
length([_|Prefix], N),
append(Prefix, [Old|Rest], List),
append(Prefix, [New|Rest], Replaced).
通过这个定义,你可以得到:
?- replace_nth1([a,b], 0, Old, x, Replaced).
false.
?- replace_nth1([a,b], 1, Old, x, Replaced).
Old = a,
Replaced = [x, b].
?- replace_nth1([a,b], 2, Old, x, Replaced).
Old = b,
Replaced = [a, x].
?- replace_nth1([a,b], 3, Old, x, Replaced).
false.
请注意,如果将第二个参数(索引)保留为变量,则可能会循环:
?- replace_nth1([a,b], N, Old, x, Replaced).
N = 1,
Old = a,
Replaced = [x, b] ;
N = 2,
Old = b,
Replaced = [a, x] ;
% does not terminate
如果您打算这样使用它,您可能需要使用输入列表的长度来约束索引:
replace_nth1(List, N, Old, New, Replaced) :-
length(List, M),
between(1, M, N),
length([_|Prefix], N),
append(Prefix, [Old|Rest], List),
append(Prefix, [New|Rest], Replaced).
这会正确终止上面的查询,并使用最通用的查询枚举解决方案:
?- replace_nth1([a,b], N, Old, x, Replaced).
N = 1,
Old = a,
Replaced = [x, b] ;
N = 2,
Old = b,
Replaced = [a, x].
?- replace_nth1(L, N, Old, New, R).
L = [Old],
N = 1,
R = [New] ;
L = [Old, _A],
N = 1,
R = [New, _A] ;
L = [_A, Old],
N = 2,
R = [_A, New] ;
L = [Old, _A, _B],
N = 1,
R = [New, _A, _B] ;
% and so on
对于矩阵,您必须嵌套执行此操作两次。