1
member(X,[X|T]).
member(X,[H|T]):-member(X,T).

delfstocc(X,[X|T],T).
delfstocc(X,[Y|T],[Y|T1]):-delfstocc(X,T,T1),!.

delallocc(X,L,L1):-member(X,L),delfstocc(X,L,R),!,delallocc(X,R,L1);write(L).

ـــــــــــ

まず、カットを使用せずにこのコードを書き、次に完璧な答えが得られるまで各述語の後にカット演算子を配置しようとしましたが、実際にはカットを使用した後の動作がわかりません。カット演算子がプロローグのマッチングの進行を停止することは知っていますが、正しく使用できないため、このコードをトレースするのに役立ちます。このコードは、リスト内の要素のすべての出現を単純に削除します。

4

1 に答える 1

1

まず、カットに関してですが、実際には以下のように扱われます。

「ゴールは成功し、親ゴールがカットが発生する節のヘッドと統合されてから行われたすべての選択に Prolog をコミットします」。

参照: http://www.swi-prolog.org/pldoc/doc_for?object=!/0

リストからの削除について: 目的を達成するためのアプローチは不必要に複雑です。より簡単な解決策は次のとおりです。

空のリストの場合、delete は常に true を保持します。

del([],_X,[]).

リストの先頭が削除しようとしている要素と同じ場合、それは他のリストに属していません:

del([X|Xs], X, Ys) :- del(Xs, X, Ys).

リストの先頭が削除する要素と同じでない場合、それは他のリストに属します:

del([X|Xs], Z, [X|Ys]) :- dif(X,Z), del(Xs, X, Ys).

(注: 句の順序は重要です! なぜ?)

このソリューションはカットを使用せず、バックトラッキングを試みます。バックトラッキングを防ぐために、適切な場所でカットを使用できます。

于 2013-03-18T14:05:49.247 に答える