剪切在Prolog中的递归谓词的末尾

pred(Args).
pred(Args) :-
    goalA,
    goalB,
    !,
    pred(Args).
pred(Args) :-
    goalC,
    goalD,
    !,
    pred(Args).

通常我会编写一个递归谓词,它与内存性能有关,与上面代码片段的内容类似.随着切割被用来试图强制尾部调用优化发生.我最近经历了一个大型的prolog代码库,并且已经找到了一些示例,其中切换实际上是在递归调用之后而不是在它之前.据推测,这可以防止尾部呼叫优化发生而不是协助它.

我的问题是,我可以将递归调用之后的剪切移动到紧接其之前而不影响程序的含义吗?这假设谓词的每个子句在相同的相对位置都有一个切口.

现在我一直在考虑它,我想也许答案是“不一定”,但是在调用之前用切割重写了所有代码并发现测试套件仍在通过,我也是想知道是否可能有其他深奥的理由来编写这样的谓词.还是只是糟糕的编码?

最佳答案 我的猜测是编码可能不好(或误解了作者在做什么)

我这样说,因为我,我自己,曾经做过同样的错误:

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 :-
       ...
点赞