Prologリストから要素を削除

2020-03-30 list prolog

リスト内の要素の出現をすべて削除する次の事実があります。出力は正しいですが、要素は空白スペースに置き換えられるだけです

remover( _, [], []).
remover( R, [R|T], [T2]) :- remover( R, T, T2).
remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2).

removerを呼び出すと、出力は次のようになります。

remover(3,[1,2,3,4,3],Res)
Res = [1, 2, [4, []]]

最初の発生のみを削除する次の事実もありますが、出力は上から同じです

remover_primeira( _, [], []).
remover_primeira( R, [R|T], [T2]) :-remover_primeira( R, T, T2),!.
remover_primeira( R, [H|T], [H|T2]) :- H \= R, remover_primeira( R, T, T2).

何が悪いのですか?

Answers

T2を2番目の句のシングルトンリストでラップしないでください。

remover( _, [], []).
remover( R, [R|T], T2) :- remover( R, T, T2).
remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2).

最初の出現のみを削除する必要がある場合は、その要素を見つけた瞬間から再帰しないでください。

remover( _, [], []).
remover( R, [R|T], T).
remover( R, [H|T], [H|T2]) :- H \= R, remover( R, T, T2).

OPコードから派生した@WillemVanOnsemによるソリューションは、削除する要素をリストの要素と比較するときに用語の統一を使用します(代わりに用語の等価性を使用することもできます)。ソリューションは基本条件で機能します。しかし、条件が根拠のない場合、予期しない結果になる可能性があります。例えば:

| ?- remover(a(_), [a(1), b(2), a(3), b(4)], List).

List = [b(2),a(3),b(4)] ? ;
no

次のremover/3述語の代替定義を検討してください。

remover(_, [], []).
remover(R, [H|T], T2) :- \+ H \= R, remover(R, T, T2).
remover(R, [H|T], [H|T2]) :- H \= R, remover(R, T, T2).

このソリューションでは、上記のクエリは次のようになります。

| ?- remover(a(_), [a(1), b(2), a(3), b(4)], List).         

List = [b(2),b(4)] ? ;
no

述語に必要なセマンティクスを明確に理解してください。

Related