Matrix Prolog在矩阵上使用findall/3

Matrix Prolog在矩阵上使用findall/3,matrix,prolog,prolog-findall,Matrix,Prolog,Prolog Findall,我的SWI序言中有以下矩阵: matrix(1,[ [*,*,*,*,*,*,*,*,*,*,*,*], [*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*], [*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*], [*,*,spots(4,3),spots(4

我的SWI序言中有以下矩阵:

 matrix(1,[  [*,*,*,*,*,*,*,*,*,*,*,*],
        [*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],
        [*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],
        [*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],
        [*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],
        [*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],
        [*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],
        [*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],
        [*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],
        [*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*]
        [*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],
        [*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]]).
我想使用findall/3谓词,这样我就可以得到所有spot(X,Y)事实的列表,比如>>>

 findall(spots(X,Y),matrix(1,Map),X). 
它应该返回如下内容:

 X = (spots(2,4), spots(2,5), spots(2,10), spots(2,11), spots(3,4) etc .... spots(12,10)). 
然而,我对如何实现这一点感到非常困惑,因为矩阵是由列表中的列表组成的。如果有人能给我看一个配置好的谓词,以便得到一个列表,我将不胜感激

谢谢你的帮助!!!-真的很感激

Edit-可能能够使用下面的代码,但无法看到如何在第二个findall/3语句中实现这一点。真的卡住了,非常感谢您的帮助。

at(Mat, Row, Col, Val) :- nth1(Row, Mat, ARow), nth1(Col, ARow, Val).

想想你的谓词应该描述什么:你想在一个由原子组成的列表中找到
点(,)
形式的所有术语

:- use_module(library(lists)).

matrix_spots([],[]).                % no spots in the empty matrix
matrix_spots([R|Rs],S) :-
    row_spots(R,RSs),               % RSs ... spots in row R
    matrix_spots(Rs,S1),            % S1 ... spots in the remaining rows
    append(RSs,S1,S).               % S ... RSs followed by S1

row_spots([],[]).                   % no spots in an empty row
row_spots([E|Es],[E|RSs]) :-        % E is in the list of spots
    E=spots(_,_),                   % if it is a spot
    row_spots(Es,RSs).              % RSs ... spots in rest of row
row_spots([*|Es],RSs) :-            % * is not in the list of spots
    row_spots(Es,RSs).              % Rss ... spots in rest of row
现在,您可以查询矩阵中的所有点:

   ?- matrix(1,M), matrix_spots(M,S).
M = [[*,*,*,*,*,*,*,*,*,*,*,*],[*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],[*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],[*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],[*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],[*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],[*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],[*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],[*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],[*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*],[*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],[*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]],
S = [spots(2,4),spots(2,5),spots(2,10),spots(2,11),spots(3,4),spots(3,5),spots(3,6),spots(3,7),spots(3,10),spots(3,11),spots(4,3),spots(4,4),spots(4,6),spots(4,7),spots(4,8),spots(4,9),spots(4,11),spots(4,12),spots(5,2),spots(5,3),spots(5,4),spots(5,5),spots(5,8),spots(5,9),spots(5,11),spots(5,12),spots(6,2),spots(6,3),spots(6,5),spots(6,6),spots(6,7),spots(6,8),spots(6,10),spots(6,11),spots(6,12),spots(7,3),spots(7,4),spots(7,6),spots(7,7),spots(7,8),spots(7,10),spots(7,11),spots(8,2),spots(8,3),spots(8,4),spots(8,6),spots(8,7),spots(8,8),spots(8,9),spots(8,11),spots(8,12),spots(9,2),spots(9,3),spots(9,5),spots(9,6),spots(9,9),spots(9,10),spots(9,11),spots(9,12),spots(10,2),spots(10,3),spots(10,5),spots(10,6),spots(10,7),spots(10,8),spots(10,10),spots(10,11),spots(11,3),spots(11,4),spots(11,7),spots(11,8),spots(11,9),spots(1ts(12,4),spots(12,9),spots(12,10)] ? ;
no
请注意,您的示例矩阵中有一个输入错误:在第10个列表的末尾缺少逗号:
…spots(10,11),*],

编辑:

以下是@mat在评论中建议的dcg版本。它确实更容易阅读:

matrix_spots(M,S) :-
    phrase(rows(M),S).

rows([]) -->                % no spots in the empty matrix
    [].
rows([R|Rs]) -->
    row(R),                 % all spots in row R
    rows(Rs).               % all spots in the remaining rows

row([]) -->                 % no spots in an empty row
    [].
row([*|Xs]) -->             % no spot at this position in the row
    row(Xs).                % but there might be in the remainder 
row([spots(A,B)|Xs]) -->    % spot at this position
    [spots(A,B)],           % is in the list
    row(Xs).                % and the spots in the rest of the row
上述查询可与此dcg版本一对一地使用

关于你在评论中的(@User15388472)findall/3问题:假设你有一个谓词矩阵\u spot/2,它匹配形式为
spots(a,B)
的一个项作为第二个参数,而不是所有spots的列表。该谓词可以如下所示:

matrix_spot([R|Rs],S) :-
    row_spot(R,S).                      % S is in row R
matrix_spot([R|Rs],S) :-                % S is not in R but
    matrix_spot(Rs,S).                  % in one of the other rows Rs

row_spot([spots(A,B)|Xs],spots(A,B)).   % head of the list is the spot
row_spot([X|Xs],S) :-
    row_spot(Xs,S).                     % S is in the tail of the list
如果你查询这个谓词,你每次会得到一个
点(A,B)
作为答案:

   ?- matrix(1,M), matrix_spot(M,S).
M = [[*,*,*,*,*,*,*,*,*,*,*,*],[*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],[*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],[*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],[*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],[*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],[*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],[*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],[*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],[*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*],[*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],[*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]],
S = spots(2,4) ? ;
M = [[*,*,*,*,*,*,*,*,*,*,*,*],[*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],[*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],[*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],[*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],[*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],[*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],[*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],[*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],[*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*],[*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],[*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]],
S = spots(2,5) ? ;
...
在这种情况下,您可以使用findall/3查找矩阵中的所有术语
spot(a,B)

   ?- matrix(1,M), findall(S,matrix_spot(M,S),Spots).
M = [[*,*,*,*,*,*,*,*,*,*,*,*],[*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],[*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],[*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],[*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],[*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],[*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],[*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],[*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],[*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*],[*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],[*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]],
Spots = [spots(2,4),spots(2,5),spots(2,10),spots(2,11),spots(3,4),spots(3,5),spots(3,6),spots(3,7),spots(3,10),spots(3,11),spots(4,3),spots(4,4),spots(4,6),spots(4,7),spots(4,8),spots(4,9),spots(4,11),spots(4,12),spots(5,2),spots(5,3),spots(5,4),spots(5,5),spots(5,8),spots(5,9),spots(5,11),spots(5,12),spots(6,2),spots(6,3),spots(6,5),spots(6,6),spots(6,7),spots(6,8),spots(6,10),spots(6,11),spots(6,12),spots(7,3),spots(7,4),spots(7,6),spots(7,7),spots(7,8),spots(7,10),spots(7,11),spots(8,2),spots(8,3),spots(8,4),spots(8,6),spots(8,7),spots(8,8),spots(8,9),spots(8,11),spots(8,12),spots(9,2),spots(9,3),spots(9,5),spots(9,6),spots(9,9),spots(9,10),spots(9,11),spots(9,12),spots(10,2),spots(10,3),spots(10,5),spots(10,6),spots(10,7),spots(10,8),spots(10,10),spots(10,11),spots(11,3),spots(11,4),spots(11,7),spots(11,8),spots(11,9),spots(11,10),spots(12,3),spots(12,4),spots(12,9),spots(12,10)]

您了解找到的代码是如何工作的吗?您是否尝试过任何东西或尝试过
findall/3
?谷歌搜索“prolog如何使用findall”立即点击。嗨@潜伏者。。。所以我尝试了下面的代码--`bagof(X,R^C^(空格(R,C),bagof(Y,N^M^(nth1(R,Xs,N),nth1(M,N,Y)),X)),Row)`——但它不断抛出一个错误,说“需要整数”。我想我只是被一袋中的另一袋弄糊涂了——这就是我目前正在努力理解的。谢谢@tas。。。真的很有帮助。为了我自己的利益,是否仍然可以使用findall/3谓词来提供相同的结果?@mat:当然,你是绝对正确的。我添加了一个dcg版本above@User15388472:我添加了另一个版本,希望能回答您关于findall/3的问题