由于您想描述一个列表,您可以选择使用 DCG。它们通常会产生非常容易阅读的代码:
matrix_indices(M,I) :-
phrase(indices(M,0),I). % the list I is described by the DCG indices//2
indices([],_) --> % if M is empty
[]. % I is empty too
indices([[0,0,0]|Ls],I0) --> % if the head of M is [0,0,0]
{I1 is I0+1}, % the current index is calculated but is not in I
indices(Ls,I1). % the same holds for the tail
indices([L|Ls],I0) --> % if the head of the list
{dif(L,[0,0,0])}, % differs from [0,0,0]
{I1 is I0+1}, % the current index is calculated
[I1], % and is in the list I
indices(Ls,I1). % the same holds for the tail
请注意,括号中的目标是普通的 Prolog 目标。如果您使用给定示例查询此谓词,您将获得所需的解决方案:
?- matrix_indices([[0,0,0],[1,0,0],[0,0,1],[1,0,0],[0,1,0],[0,0,0],[0,1,0],[0,1,0],[0,0,0]],I).
I = [2,3,4,5,7,8] ? ;
no
您也可以在另一个方向使用谓词,但您必须要求一个具体的长度或为目标添加前缀length(M,_),以防止谓词循环。例如查询...
?- length(M,_), matrix_indices(M,[2,3,4,5,7,8]).
M = [[0,0,0],_A,_B,_C,_D,[0,0,0],_E,_F],
dif(_A,[0,0,0]),
dif(_B,[0,0,0]),
dif(_C,[0,0,0]),
dif(_D,[0,0,0]),
dif(_E,[0,0,0]),
dif(_F,[0,0,0]) ? ;
M = [[0,0,0],_A,_B,_C,_D,[0,0,0],_E,_F,[0,0,0]],
dif(_A,[0,0,0]),
dif(_B,[0,0,0]),
dif(_C,[0,0,0]),
dif(_D,[0,0,0]),
dif(_E,[0,0,0]),
dif(_F,[0,0,0]) ? ;
M = [[0,0,0],_A,_B,_C,_D,[0,0,0],_E,_F,[0,0,0],[0,0,0]],
dif(_A,[0,0,0]),
dif(_B,[0,0,0]),
dif(_C,[0,0,0]),
dif(_D,[0,0,0]),
dif(_E,[0,0,0]),
dif(_F,[0,0,0]) ?
.
.
.
...按预期产生无限多的答案。