5

(これはコースワークの質問ではありません。私自身の個人的な学習です。)

リストから要素を削除するために Prolog で演習を行おうとしています。これが私のコードです:

deleteall([],X,[]).
deleteall([H|T],X,Result) :- 
    H==X,
    deleteall(T,X,Result).
deleteall([H|T],X,[H|Result]) :- deleteall(T,X,Result).

テストすると、最初に良い答えが得られます (つまり、すべての X が削除されます)。しかし、バックトラックにより、X のインスタンスの一部が削除された、またはまったく削除されていないリストの他のすべてのバリアントが提供されます。

なぜこれが必要なのですか?H==X が最後の句まで落ちるのはなぜですか?

4

2 に答える 2

6

を比較に使用する場合は(==)/2、3 番目のルールで反対の が必要になります(\==)/2。一方、そのような定義はもはや純粋な関係ではありません。これを見るには、deleteall([X],Y,Zs), X = Y.

純粋な関係には と が必要(=)/2ですdif/2。SWI、YAP、B、SICStus などの多くのプロローグが提供していますdif/2

deleteall([],X,[]).
deleteall([H|T],X,Result) :- 
    H=X,
    deleteall(T,X,Result).
deleteall([H|T],X,[H|Result]) :-
    dif(H,X),
    deleteall(T,X,Result).

の答えを見てくださいdeleteall([X,Y],Z,Xs)

編集(4年後):

より効率的ですが、同じ純粋な流れで、これは and を使用して記述できif_/3ます(=)/3

deleteall([], _X, []).
deleteall([E|Es], X, Ys0) :-
   if_( E = X, Ys0 = Ys, Ys0 = [E|Ys] ),
   deleteall(Es, X, Ys).
于 2011-06-22T14:43:08.787 に答える
2

最後の節はX、リストから削除する場合、head 要素は (その値とは関係なく) 残る可能性があることを示しています。Prolog は、前の句の条件が true であるか、別の句が失敗した場合にこの句に戻るかどうかに関係なく、適切と思われるときにいつでもこの句を使用することが;できます。次のソリューションを取得するレベル)。head 要素が equalXでない可能性があるという条件を追加すると、機能するはずです。

編集:最初に開いた誤ったアサーションを削除しました。

于 2011-06-22T14:30:01.837 に答える