これはかなりうまく書かれていません。
even_numbers(X , R) :-
even_numbers(X , [] , T) ,
reverse(T , R).
even_numbers([] , T , T).
even_numbers([X|Xs] , T , R) :-
Z is X mod 2 ,
Z == 0 ,
! ,
even_numbers(Xs , [X|T] , R).
even_numbers([_|Xs] , T , R) :-
even_numbers(Xs , T , R).
最初の述語は、even_numbers/2
述語は公共ラッパーです:あなたはそれを少しリファクタリングし、それを末尾再帰を行う場合、理解しやすいかもしれません。それはプライベートヘルパー、even_numbers/3
を呼び出し、偶数のリストを逆の順序で返します。それはそれを逆にし、ラッパーに渡された結果と、それを統一しようとします。ソースリストが空の場合
- : ヘルパーメソッドは、これを行う結果とアキュムレータ(T)を統一します。
- ソースリストが空でない場合、リスト(X)の頭部がアキュムレータにXを押し、さらに、
- ソースリストが空でない場合、リスト(X)の頭部がアキュムレータを変更せず
しかし、@アンドレParamésで述べたように、デバッガでそれを介して動作し、それが何が起こっているのか明らかになるだろう。
Tedの回答は良いですが、プログラムをファイルに保存し、プロローグインタプリタを起動し、プログラム( '[filename] .')を読み込み、トレースを開始して(' trace.'を使って)、 'even_number'ルールをリストに追加します。それがどのように動作するかを理解しようとすると、その実行を段階的に見ることは非常に役に立ちます。 –