【问题标题】:Prolog- Convert a matrix to a list with indicesProlog-将矩阵转换为带有索引的列表
【发布时间】:2017-11-18 23:29:07
【问题描述】:

我有一个这样的矩阵:

[[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]]

当行不是[0,0,0] 时,我需要一个保存索引的列表。 所以我的例子中的结果应该是:

[2,3,4,5,7,8]

我在 Prolog 中编写递归程序时遇到问题,因为我还没有真正弄清楚它是如何工作的。

首先将矩阵转换为向量可能会有所帮助吗?不管是[1,0,0] 还是[0,1,0]。唯一重要的是它不是[0,0,0]

【问题讨论】:

  • 将代码格式化为代码样式而不是引号样式。

标签: list matrix prolog


【解决方案1】:

由于您想描述一个列表,您可以选择使用 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]) ? 
.
.
.

...按预期产生无限多的答案。

【讨论】:

    【解决方案2】:

    我将如何使用 findall/3 和 nth1/3 解决:

    ?- M = [[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]],
       findall(I, (nth1(I,M,E), E\=[0,0,0]), L).
    L = [2, 3, 4, 5, 7, 8]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-03
      • 2022-01-25
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      相关资源
      最近更新 更多