0

私はコードを持っています:

locdiff([A|T], [A|_], T).
locdiff([H|T], L2, [H|T2]) :-
    locdiff(T, L2, T2). 

でテストするとlocdiff([(a,1), (b,2), (b,3), (c,3), (c,4)], [(b,_)], L3)、 の 1 つだけが見つかり、削除[(b,_)]され(b,2)ます。(b,2)と の両方を見つけて削除する必要があり(b,3)ます[(b,_)]。誰かが私が逃したもので私を助けることができますか?

4

2 に答える 2

0

何かが必要かもしれません:

locdiff([], _, []).

locdiff([(b,_)|T], [(b,_)], T1) :-
    !, locdiff(T, [(b,_)], T1).

locdiff([H|T], L2, [H|T2]) :-
    locdiff(T, L2, T2).

しかし、なぜあなたは[A | _]リストに要素が1つしかない場合は?

[編集]忘れました!2番目のルールで

于 2013-02-25T12:32:01.990 に答える
0

larsman のヒントに従う場合に注意する価値のある技術的な複雑さがあり、この方法で直接実装します

locdiff([], _, []).
locdiff([A|T], [A|_], R) :-
    !, locdiff(T, [A|_], R).
locdiff([H|T], L2, [H|T2]) :-
    locdiff(T, L2, T2).

これとともに

?- locdiff([(a,1), (b,2), (b,3), (c,3), (c,4)], [(b,_)], L3).
L3 = [ (a, 1), (b, 3), (c, 3), (c, 4)].

最初のインスタンスが削除され、最後のインスタンスが削除されていることがわかります。これは、最初の一致で無名変数がバインドされ、最後の一致を除いて後続の一致が禁止されるためです。(b,_)

次に、完了した手順は次のようになります

locdiff([], _, []).
locdiff([H|T], [A|_], R) :-
    \+ \+ H = A,  % double negation allows matching without binding
    !, locdiff(T, [A|_], R).
locdiff([H|T], L2, [H|T2]) :-
    locdiff(T, L2, T2).

今、結果はあなたが必要としているものです。

または、過度のバインディングを避けて、パターン マッチングをより正確にする必要があります。

locdiff([], _, []).
locdiff([(A,_)|T], [(A,_)|_], R) :-
    !, locdiff(T, [(A,_)|_], R).
locdiff([H|T], L2, [H|T2]) :-
    locdiff(T, L2, T2).

?- locdiff([(a,1), (b,2), (b,3), (c,3), (c,4)], [(b,_)], L3).
L3 = [ (a, 1), (c, 3), (c, 4)].

SWI-Prolog で /3 を除外するなど、一部のライブラリには特定の機能があることに注意してください。

eq([(E,_)|_], (E,_)).
locdiff(L, E, R) :-
  exclude(eq(E), L, R).
于 2013-02-25T13:31:24.223 に答える