質問
pred(Args).
pred(Args) :-
goalA,
goalB,
!,
pred(Args).
pred(Args) :-
goalC,
goalD,
!,
pred(Args).
通常、私は上記のコードスニペットの線に沿ってメモリパフォーマンスの何かを心配していた再帰的な述語を記述します。カットで発生することが末尾呼び出しの最適化を強制しようとするために使用されています。私は最近、大規模なプロローグのコードベースを通過されているとカットが再帰呼び出した後ではなく、その直前に実際にいくつかの例を発見しました。おそらく、これはそれを支援するのではなく、起きてから末尾呼び出しの最適化を防止する効果があります。
私の質問は、私はプログラムの意味に影響を与えることなく、直前にそれへの再帰呼び出し後からカットを移動することができますか?これは、述語の各句の同じ相対位置に切れ目があると仮定している。
今、私はいくつかのより多くのそれについて考えてきた、私は私が、答えは「必ずしも」であるかもしれないと思っていますが、コールの前にカットして、すべてのコードを書き換えたとテストスイートがまだ通過していることを発見しますこのような述語を書くためのいくつかの他の難解な理由があるかもしれない場合も不思議「メートル。それとも、単に悪いコーディングのですか?
解決
私の推測では、それが悪いコーディング(または何をやっていた著者の誤解)されるかもしれないということです。
私は、自分自身が、かつて同じエラーをしたので、私は、このことを言ってます:
ます。https://mailbox.iai .uni-bonn.de /郵便配達/公共/ SWI-プロローグ/ 2009 / 001540.htmlする
http://xonix.habrahabr.ru/blog/60430/する(警告、ロシア語)
しかし、SWIのメーリング・リストから、人々は末尾再帰コードの正しい方法があることを確認した。
head :-
<guard goals>, !,
<deterministic stuff>,
head.
head :-
...
所属していません StackOverflow