Prolog中递归谓词末尾的剪切

Prolog中递归谓词末尾的剪切,prolog,prolog-cut,Prolog,Prolog Cut,通常,我会编写一个递归谓词,它与内存性能有关,就像上面的代码片段一样。使用cut试图强制进行尾部调用优化。我最近研究了一个大型的prolog代码库,发现了一些示例,其中cut实际上在递归调用之后,而不是在它之前。这可能会阻止尾部调用优化的发生,而不是帮助它 我的问题是,我是否可以在不影响程序含义的情况下,将剪切从递归调用之后移动到它之前?这是假设谓词的每个子句在相同的相对位置上都有一个切口 现在我一直在思考这个问题,我想也许答案是“不一定”,但是在调用之前用cut重写了所有代码,发现测试套件仍然

通常,我会编写一个递归谓词,它与内存性能有关,就像上面的代码片段一样。使用cut试图强制进行尾部调用优化。我最近研究了一个大型的prolog代码库,发现了一些示例,其中cut实际上在递归调用之后,而不是在它之前。这可能会阻止尾部调用优化的发生,而不是帮助它

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


现在我一直在思考这个问题,我想也许答案是“不一定”,但是在调用之前用cut重写了所有代码,发现测试套件仍然通过,我还想知道是否还有其他一些深奥的原因来编写这样的谓词。还是仅仅是糟糕的编码?

我猜可能是糟糕的编码(或者误解了作者所做的事情)

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

(警告,俄语)

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

pred(Args).
pred(Args) :-
    goalA,
    goalB,
    !,
    pred(Args).
pred(Args) :-
    goalC,
    goalD,
    !,
    pred(Args).
标题:-
, !,
,
头。
负责人:-
...

由于我移动剪切并没有改变代码在所有测试用例中的行为方式,我认为您可能是对的——这只是糟糕的编码。
head :-
       <guard goals>, !,
       <deterministic stuff>,
       head.
head :-
       ...