【问题标题】:Cuts at the end of recursive predicates in PrologProlog中递归谓词末尾的剪切
【发布时间】:2009-08-27 08:23:25
【问题描述】:
pred(Args).
pred(Args) :-
    goalA,
    goalB,
    !,
    pred(Args).
pred(Args) :-
    goalC,
    goalD,
    !,
    pred(Args).

通常我会编写一个与内存性能相关的递归谓词,类似于上面的 sn-p 代码行。使用 cut 试图强制进行尾调用优化。我最近浏览了一个大型 prolog 代码库,并发现了一些示例,其中剪切实际上是在递归调用之后而不是紧接在它之前。据推测,这具有防止尾调用优化发生而不是辅助它的效果。

我的问题是我可以在不影响程序含义的情况下将递归调用之后的剪切移动到它之前吗?这是假设谓词的每个子句在相同的相对位置都有一个切分。

现在我一直在考虑更多,我在想答案可能是“不一定”,但是在调用之前用剪切重写了所有代码并发现测试套件仍然通过,我我还想知道是否还有其他一些深奥的原因来编写这样的谓词。还是只是编码不好?

【问题讨论】:

    标签: prolog prolog-cut


    【解决方案1】:

    我的猜测是它可能是错误的编码(或误解了作者在做什么)

    我这么说是因为我自己曾经犯过同样的错误:

    https://mailbox.iai.uni-bonn.de/mailman/public/swi-prolog/2009/001540.html

    http://xonix.habrahabr.ru/blog/60430/(警告,俄语)

    但是来自 SWI 邮件列表的人证实尾递归代码的正确方式是

    head :-
           <guard goals>, !,
           <deterministic stuff>,
           head.
    head :-
           ...
    

    【讨论】:

    • 由于我移动剪辑并没有改变代码在我们所有测试用例中的行为方式,我想你可能是对的 - 这只是糟糕的编码。
    猜你喜欢
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多