我正在尝试编写一个名为“range”的谓词,它创建指定范围内的整数列表。
示例:
range(4,9, L).
L = [4,5,6,7,8,9]
我编写的谓词似乎工作正常,但当它完成时,我可以点击“下一步”,然后它返回:
L = [4, 5, 6, 7, 8, 9, _1200|_1202]
这是我的代码:
range(Low, Low, [Low]). %base case, if low and high are equal
range(Low, High, [H|T]):-
Low > High,
!; %if low is greater than high cut
H is Low, %set the head of the list
Num is Low + 1, %increment low by 1
range(Num, High, T). %recursive call
如果给出了无效范围,我还希望它返回一个空列表。例如:
range(10, 4, L).
应该返回一个空列表。相反,我得到:
L = [_1164|_1166]
我如何调整它,以便它返回一个空列表,而不是(我假设的)头部和尾部的地址。
这是我追踪时的样子:
最佳答案
例如,您可以简化控制流程
range(Low, Low, [Low]). %base case, if low and high are equal
range(Low, High, [Low|T]):- %set the head of the list
Low < High,
Num is Low + 1, %increment low by 1
range(Num, High, T). %build the tail
现在第二个子句将仅涵盖预期的情况。
关于您的解决方案,当Low>High
条件成功时,剪切也成功,并且[H|中的变量T]
没有获得任何绑定(bind)(仍然未实例化),而该子句也成功。修复将强制规则失败:
range(Low, Low, [Low]). %base case, if low and high are equal
range(Low, High, [H|T]):- %set the head of the list
Low > High,
!, fail; % force failure
H is Low,
Num is Low + 1, %increment low by 1
range(Num, High, T). %recursive call
但这将为计算的每个元素留下无用的选择点。
编辑
这里可以获取满足您要求的空列表:
range(Low, High, R):-
( Low > High
-> R = []
; R = [Low|T],
Num is Low + 1,
range(Num, High, T)
).
注意我删除了第一个子句(基本递归,现在由第一个分支覆盖),并使用了更容易阅读的“if-then-else” ' 构建。对于我们的代码片段,它相当于:
range(Low, High, R):-
( Low > High,
!, R = []
; R = [Low|T],
Num is Low + 1,
range(Num, High, T)
).
关于recursion - 递归谓词在到达基本情况后继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53690008/