Prolog - 返回矩阵的第n行

Sau*_*cia 5 counter list matrix prolog

我正在尝试编写一个rowN/3返回矩阵的第n个元素(在本例中为行)的谓词.例:

?- rowN([[1,2],[3,4],[5,6]], 2, R). 
R = [3,4];
No
Run Code Online (Sandbox Code Playgroud)

我正在与柜台挣扎.我试图找到一些非常相似的例子,但没有成功.到目前为止,我已经设法写了这个:

码:

rowN(L,[],[]).
rowN([],X,[]).
rowN([],[],[].
rowN([H|T],X,R) :-
    A==X,
    A is A + 1,
    rowI(T,A,H).
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 5

这一行没有多大意义:

rowN(L,[],[]).
Run Code Online (Sandbox Code Playgroud)

因为第二个参数是一个整数(如果我理解正确的话),你使用一个列表。几乎所有的论点都是这种情况。此外,您RowI在递归调用中使用?

解决方案

一个解决方案是首先指定第一行 ( I = 1), 等于矩阵的头:

rowN([H|_],1,H).
Run Code Online (Sandbox Code Playgroud)

接下来,您需要找到一种迭代方式来枚举您的矩阵。所以标题绝对是以下形式:

rowN([H|T],I,X) :-
#   ...
Run Code Online (Sandbox Code Playgroud)

现在我们假设I不等于1(我们稍后会讨论这个话题)。在这种情况下,我们需要进一步遍历矩阵,因此我们将取尾部并将计数器设置为I一。这可以使用:

rowN([_|T],I,X) :-
    I1 is I-1,
    rowN(T,I1,X).
Run Code Online (Sandbox Code Playgroud)

所以我们的谓词是:

rowN([H|_],1,H).
rowN([_|T],I,X) :-
    I1 is I-1,
    rowN(T,I1,X).
Run Code Online (Sandbox Code Playgroud)

现在,如果您使用此谓词,它将给出正确的结果:

?- rowN([[1,2],[3,4],[5,6]], 2, R).
R = [3, 4] ;
false.
Run Code Online (Sandbox Code Playgroud)

问题是为什么谓词不生成其他结果:在显示第一个结果后,对于rowN([[1,2],[3,4],[5,6]], 2, R) :- rowN([[3,4],[5,6]],1,[3,4]).,它可以尝试寻找替代方案。它通过使用第二个子句来做到这一点,但是它最终会用完行并调用rowN([],_,_)谓词,因为没有子句匹配,它会失败。

这个解决方案并不完美:它不能在所有方向上都正确工作,这在 Prolog 中通常很难。这就是优秀的 Prolog 程序员编写库的原因。

使用的内置nth1/3

您可以使用nth1/3swi-prolog中的谓词,而不是重新发明轮子。尽管参数被交换了 - 你需要这样称呼它nth1(2,[[1,2],[3,4],[5,6]],R).- 它的优点是它可以在更多方向上工作,大多数人可以在快速解决方案中提出,它几乎可以肯定没有错误(因为它已经被测试了数十亿次所有使用谓词的 Prolog 程序),其中一些内置函数是用 C++ 实现的,这使得它们有时更快。例如:

?- nth1(2, [[1,2],[3,4],[5,6]], R).
R = [3, 4].

?- nth1(I, [[1,2],[3,4],[5,6]], [5,6]).
I = 3.

?- nth1(I, [[1,2],[3,4],[5,6]], R).
I = 1,
R = [1, 2] ;
I = 2,
R = [3, 4] ;
I = 3,
R = [5, 6].

?- nth1(I,M,[2,3]).
I = 1,
M = [[2, 3]|_G23] ;
I = 2,
M = [_G22, [2, 3]|_G26] ;
I = 3,
M = [_G22, _G25, [2, 3]|_G29] ;
I = 4,
M = [_G22, _G25, _G28, [2, 3]|_G32] .
Run Code Online (Sandbox Code Playgroud)

因此,您可以询问第二行是什么,询问该行[5,6]的位置,通过使用索引I和行的元组进行回答来使查询更通用,并在某处R生成一个带有行的矩阵[2,3]

  • 这个回答太有见地了!谢谢@CommuSoft (3认同)