在Prolog中查找列表长度

时间:2014-05-30 17:11:03

标签: list prolog

我正在运行Prolog并尝试编写一个返回列表长度的小函数:

len([],0).
len([XS], Y) :-
    len([X|XS], M),
    Y is M+1.

我的逻辑是递归调用应包括列表尾部(XS)并将前一长度增加1(Y为M + 1。)

这总是返回false。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

以下是调试和测试Prolog谓词的一般方法:

从最常见的查询开始!

想一想:在Prolog中,您不需要编写一些测试数据。你根本不需要理解一个谓词:只需提交自由变量!这总是一个专业的举动!

所以在你的情况下,那是

?- len(L,N).
L = [],
N = 0 ;
*LOOPS**

你的定义并不像你声称的那样糟糕:至少,空列表是正确的。

现在,请查看您可能收到的编译器警告:

Warning: user://1:11:
        Singleton variables: [X]

接下来,从箭头:- 的方向读取递归规则,即从右到左:

如果len([X|Xs], M)为真且Y is M+1为真,如果一切正确,我们可以得出结论

len([XS], Y)也是如此。所以你总是总结一下长度为1的列表([Xs])。

您需要将其重新制定为len([X|Xs], M) :- len(Xs, N), Y is M+1

这是另一种策略:

概括您的计划

通过删除目标,我们可以推广一个程序 1 。这是我最喜欢的方式。通过像这样添加谓词(*)/1

:- op(950,fy, *).

*_.

现在,让我们从你的程序中删除所有目标:

len([],0).
len([XS], Y) :-
    * len([X|XS], M),
    * Y is M+1.

我们现在所拥有的是一种概括。我们将再次查看最常见查询的答案:

?- len(L, N).
L = [],
N = 0 ;
L = [_].

什么? len/2仅适用于长度为0和1的列表。这意味着,即使len([1,2], N)也会失败!所以现在我们确切地知道:必须修复程序剩余部分中的某些内容。实际上,[XS]只描述了长度为1的列表。所以必须将其删除......


精美印刷:

1适用某些限制。从本质上讲,你的程序必须是一个纯粹的,单调的程序。