Prolog等效规则,但错误在一个

时间:2015-04-04 11:38:57

标签: prolog predicate

我目前正在练习Prolog进行考试,当我学习旧考试时,我遇到了一个问题,即必须定义一个返回列表长度的谓词。 (例如:lengthof([a,b,c,d,e,f],Length).评估为Length=6.

我的方法如下:

lengthof([],0).
lengthof(List,LengthNew) :- lengthof([_|List],Length),LengthNew is Length-1.

但它总是引发堆栈溢出错误。我不知道自己做错了什么,所以我看了一下解决方案。该问题的解决方案如下:

lengthof([],0).
lengthof([_|List],LengthNew) :- lengthof(List,Length),LengthNew is Length+1.

我现在想知道为什么我的方法没有成功。这个有什么问题?我认为,从逻辑上看,两种方法都是等价的。

1 个答案:

答案 0 :(得分:2)

lengthof([],0).

此字符串表示空列表的长度为零。

lengthof([_|List],LengthNew) :- 
  lengthof(List,Length),LengthNew is Length+1.

在你说的规则中,没有空列表必须考虑作为第一个元素(_)和其他元素(List)。所有列表的长度都是" List"加一。

但是在这条规则中:

lengthof(List,LengthNew) :- 
  lengthof([_|List],Length),LengthNew is Length-1.

你说初始列表的长度(" List")是更大的列表减去1的长度。 对于任何列表都是如此,但它不能解决您的问题,因为您的代码不会计算初始列表的长度 - 而是这样您无休止地将初始列表包含在内。

处理空列表的第一个规则会消除递归退出的条件。因此,您的第二条规则必须减少列表的大小,但是您尝试增加它,因此您会收到"堆栈溢出"错误。