pred(Args).
pred(Args) :-
goalA,
goalB,
!,
pred(Args).
pred(Args) :-
goalC,
goalD,
!,
pred(Args).
通常我会编写一个与内存性能相关的递归谓词,与上面代码片段的内容类似。随着切割被用来试图强制尾部调用优化发生。我最近经历了一个大型的prolog代码库,并且已经找到了一些示例,其中切换实际上是在递归调用之后而不是在它之前。据推测,这可以防止尾部呼叫优化发生而不是协助它。
我的问题是,我是否可以在递归调用之后将剪切移动到紧接其之前而不影响程序的含义?这假设谓词的每个子句在相同的相对位置都有一个切口。
现在我已经考虑了一些,我想也许答案是“不一定”,但是在调用之前用剪切重写了所有代码并发现测试套件仍在通过,我我也想知道是否可能有其他深奥的理由来编写这样的谓词。或者只是编码不好?
答案 0 :(得分:2)
我的猜测是编码可能不好(或误解了作者在做什么)
我这样说,因为我,我自己也曾犯过同样的错误:
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 :-
...