如何用序言中的给定字母替换矩阵中的给定坐标

问题描述 投票:0回答:2

我是 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)
    ).    

      ```
prolog
2个回答
-1
投票

替换列表中的元素:

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


-1
投票

要通过索引替换元素,您可以使用 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

对于矩阵,您必须嵌套执行此操作两次。

© www.soinside.com 2019 - 2024. All rights reserved.