想想你的谓词应该描述什么:你想spots(_,_)
在一个列表列表中找到所有形式的术语,否则这些列表由 atom 组成*
。
:- 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 问题:想象一下,您有一个谓词 matrix_spot/2 匹配形式的一个术语spots(A,B)
作为第二个参数,而不是所有点的列表。该谓词可能看起来像这样:
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
如果你查询这个谓词,你会一spots(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 查找spots(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)]