【发布时间】:2014-07-27 07:18:40
【问题描述】:
我正在编写一些递归 Prolog 谓词,并遇到了我目前不太理解的某个点。
例如,我写了谓词split/3,它将整数列表分为非负整数列表和负整数列表:
版本 1
split([], [], []).
split([ListHead|ListTail], [ListHead|PList], NList) :-
ListHead >= 0,
split(ListTail, PList, NList).
split([ListHead|ListTail], PList, [ListHead|NList]) :-
ListHead < 0,
split(ListTail, PList, NList).
但在得到那个解决方案之前,我写了下面的解决方案,并想知道为什么它不起作用:
第 2 版
split([], [], []).
split([ListHead|ListTail], PList, NList) :-
ListHead >= 0,
split(ListTail, [ListHead|PList], NList).
split([ListHead|ListTail], PList, NList) :-
ListHead < 0,
split(ListTail, PList, [ListHead|NList]).
地点:
- 第一个给定参数分为
ListHead和ListTail。 - 如果
ListHead元素(整数)大于或等于 0,则将其添加到非负整数列表的前面,并使用未经处理的Nlist进行递归调用的参数。 - 如果
ListHead元素(整数)小于 0,则将其添加到负整数列表的前面,并用作带有未经处理的PList的递归调用的参数。
我不明白为什么第 2 版不起作用;它编译时没有任何警告,但只会返回 false。与上述版本的唯一区别是整数元素到Nlist 或PList 的前置是在谓词定义中(在:- 运算符之后)完成的,而不是在谓词调用的参数中。对我来说,将结果作为下一次调用的参数的一部分预先设置是有意义的......
我觉得我错过了 Prolog 递归调用的“搜索”方式!
有人能解释一下为什么第 1 版按预期工作,而第 2 版不能按预期工作吗?
【问题讨论】: