Prolog-返回矩阵的第n行

索尔·加西亚(Saul Garcia)

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

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

我在柜台上挣扎。我尝试找到一些非常相似的示例均未成功。到目前为止,我已经设法编写了以下代码:

代码:

rowN(L,[],[]).
rowN([],X,[]).
rowN([],[],[].
rowN([H|T],X,R) :-
    A==X,
    A is A + 1,
    rowI(T,A,H).
威廉·范昂塞姆

这行没有多大意义:

rowN(L,[],[]).

因为第二个参数是整数(如果我理解正确的话),并且您使用列表。您几乎所有的论据都是如此。此外,您RowI在递归调用中使用吗?

解决方案

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

rowN([H|_],1,H).

接下来,您需要找到一种迭代方法来枚举矩阵。因此,标题肯定是某种形式的:

rowN([H|T],I,X) :-
#   ...

现在,我们假定这I不等于1(稍后将讨论此主题)。在这种情况下,我们需要进一步遍历矩阵,所以我们将尾巴I放回原处,并将计数器放回原处。可以使用以下方法完成:

rowN([_|T],I,X) :-
    I1 is I-1,
    rowN(T,I1,X).

因此我们的谓词为:

rowN([H|_],1,H).
rowN([_|T],I,X) :-
    I1 is I-1,
    rowN(T,I1,X).

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

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

问题是为什么谓词不生成其他结果:在显示第一个结果for之后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] .

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章