pred(Args).
pred(Args) :-
goalA,
goalB,
!,
pred(Args).
pred(Args) :-
goalC,
goalD,
!,
pred(Args).
通常我会编写一个与内存性能相关的递归谓词,与上面代码片段的内容类似 . 使用剪切试图强制进行尾调用优化 . 我最近经历了一个大型的prolog代码库,并且已经找到了一些示例,其中切换实际上是在递归调用之后而不是在它之前 . 据推测,这可以防止尾部呼叫优化发生而不是协助它 .
我的问题是,我可以将递归调用后的剪切移动到紧接其之前而不影响程序的含义吗?这假设谓词的每个子句在相同的相对位置都有一个切口 .
现在我已经考虑了一些,我想也许答案是“不一定”,但是在调用之前用剪切重写了所有代码并发现测试套件仍在通过,我也是想知道是否可能有其他深奥的理由来编写这样的谓词 . 还是只是编码不好?
1 回答
我的猜测是编码可能不好(或误解了作者在做什么)
我这样说,因为我,我自己,曾经做过同样的错误:
https://mailbox.iai.uni-bonn.de/mailman/public/swi-prolog/2009/001540.html
http://xonix.habrahabr.ru/blog/60430/(警告,俄语)
但来自SWI邮件列表的人确认了尾递归代码的正确方法