我目前正在练习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.
我现在想知道为什么我的方法没有成功。这个有什么问题?我认为,从逻辑上看,两种方法都是等价的。
答案 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的长度。 对于任何列表都是如此,但它不能解决您的问题,因为您的代码不会计算初始列表的长度 - 而是这样您无休止地将初始列表包含在内。
处理空列表的第一个规则会消除递归退出的条件。因此,您的第二条规则必须减少列表的大小,但是您尝试增加它,因此您会收到"堆栈溢出"错误。