8

プロローグでリスト差分ルーチンを実装しようとしています。何らかの理由で、以下が失敗します。

difference(Xs,Ys,D) :- difference(Xs,Ys,[],D).
difference([],_,A,D) :- D is A, !.
difference([X|Xs],Ys,A,D) :-
  not(member(X,Ys)),
  A1 is [X|A],
  difference(Xs,Ys,A1,D).

しようとすると:

?- difference([1,2],[],D).

次のエラーが表示されます。

ERROR: '.'/2: Type error: `[]' expected, found `1' ("x" must hold one character)
^  Exception: (10) _L161 is [2|1] ? 
4

4 に答える 4

10

あなたの使い方 A1 is [X|A] は正しくありません。述語isは算術のみに使用されます。ところで、SWI-Prolog には組み込みの減算述語があります。

1 ?- subtract([1,2,3,a,b],[2,a],R).
R = [1, 3, b].

2 ?- listing(subtract).
subtract([], _, []) :- !.
subtract([A|C], B, D) :-
        memberchk(A, B), !,
        subtract(C, B, D).
subtract([A|B], C, [A|D]) :-
        subtract(B, C, D).

true.

これはあなたが必要とするものですか?

于 2009-10-06T12:52:05.940 に答える
3
minus([H|T1],L2,[H|L3]):-
    not(member(H,L2)),
    minus(T1,L2,L3).
minus([H|T1],L2,L3):-
    member(H,L2),
    minus(T1,L2,L3).
minus([],_,[]). 

minus([1,2,3,4,3], [1,3], L).

output: L=[2,4]
于 2011-07-08T18:41:04.103 に答える
2
always (subtructLists(List, [Head|Rest], Result): -
       ( 
          delete_element(Head, List, Subtructed)
        , !
        , subtructLists(Subtructed, Rest, Result)
       ) ; (
          subtructLists(List, Rest, Result)
       )
).

always (subtructLists(List, [], List)).

always( delete_element(X, [X|Tail], Tail)).

always( delete_element(X, [Y|Tail1], [Y|Tail2]): -
        delete_element(X, Tail1, Tail2)
).
于 2012-12-13T17:54:12.917 に答える
2

find all ソリューションを使用すると、次のようになります。

difference(Xs,Ys,D) :- 
  findall(X,(member(X,Xs),not(member(X,Ys))),D).
于 2009-10-06T02:52:31.930 に答える