recursion - 递归谓词在到达基本情况后继续

标签 recursion prolog

我正在尝试编写一个名为“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]

我如何调整它,以便它返回一个空列表,而不是(我假设的)头部和尾部的地址。

这是我追踪时的样子:

Trace

最佳答案

例如,您可以简化控制流程

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/

相关文章:

Java - 从递归函数返回

java - java中如何实现递归除法

recursion - 归纳类型和 nat 上的相互递归

python - 检查一个不平等制度是否会带来另一个平等制度?

序言:一个人是他自己的 sibling ?

list - Lisp,关于列表和递归的几个问题

javascript - 如何递归地计算它在对象中出现的目标键(属性)的数量?

list - 有没有办法使用 write/1 来编写 length/1 谓词来打印结果?

prolog - Prolog 中使用 Peano 数的递归加法不起作用

prolog - 尝试在 Prolog 中生成非零整数列表