List 在prolog的列表中删除该值以及该值的所有重复项

List 在prolog的列表中删除该值以及该值的所有重复项,list,prolog,prolog-dif,List,Prolog,Prolog Dif,在prolog中从列表中删除值时遇到一些问题。 我有一个颜色列表,我想添加一个颜色列表,保留所有没有重复的值,并删除其余的 [green, red, blue, purple, yellow, brown, orange, black, purple] 所以紫色在这个列表中出现了两次,我想把它们都删除。 这是我想要返回的列表 [green, red, blue, yellow, brown, orange, black] 我目前有这个删除所有的重复,但我不能得到两个紫色了 mymember(

在prolog中从列表中删除值时遇到一些问题。 我有一个颜色列表,我想添加一个颜色列表,保留所有没有重复的值,并删除其余的

[green, red, blue, purple, yellow, brown, orange, black, purple]
所以紫色在这个列表中出现了两次,我想把它们都删除。 这是我想要返回的列表

[green, red, blue, yellow, brown, orange, black]
我目前有这个删除所有的重复,但我不能得到两个紫色了

mymember(X,[H|_]) :- X==H,!.
mymember(X,[_|T]) :- mymember(X,T).

not(A) :- \+ call(A).

set([],[]).
set([Head|Tail],[Head|Out]) :-
    not(mymember(Head,Tail)),
    set(Tail, Out).
set([Head|Tail],Out) :-
    mymember(Head,Tail),
    set(Tail, Out).
这就是我现在得到的结果:

[green, red, blue, yellow, brown, orange, black, purple]

我认为你的思路是对的。这里有一个使用->的方法;构造并利用delete/3谓词,删除所有重复项:

remdup([], _, []).
remdup([H|T], X, R) :-
    (   H == X
    ->  (   member(X, T)
        ->  delete(T, X, R)     % only delete if it's in the list more than once
        ;   R = [H|R1],
            remdup(T, X, R1)
        )
    ;   R = [H|R1],
        remdup(T, X, R1)
    ).
另一种解决方案是使用
select/3
以及
delete/3

remdup(L, X, R) :-
    (select(X, L, L1), select(X, L1, L2))
->  delete(L2, X, R)
;   L = R.
select/3
从列表中提取元素的一个实例。如果找不到元素,则失败。所以在上面,如果我们能够找到至少两个实例,我们将删除所有实例。
完成整个列表的解决方案(减去指定要删除的单个项的中间参数):


我通过这样做修复了它:

my_delete(Res, [], Res).
my_delete(Colorslist, [Head|Tail], R) :-  
    my_delete_worker(Colorslist, Head, Result), 
    my_delete(Result, Tail, R).

my_delete_worker([], _, []).
my_delete_worker([X|T], X, R) :-
    my_delete_worker(T, X, R).
my_delete_worker([H|T], X, [H|R]) :-
    X \= H,
    my_delete_worker(T, X, R).
我忘了将第一种颜色的结果放入第二种颜色的颜色列表中。当它到达基本情况下,我统一我的颜色列表与结果。
谢谢你的帮助潜伏者

简单的方法…一行:

singletons(Xs,Zs) :-
  findall( X , ( append(P,[X|S],Xs), \+member(X,P), \+member(X,S) ) , Zs )
  .
与…结合使用

OP给出的示例查询具有预期结果:

?- list_uniqs([green,red,blue,purple,yellow,brown,orange,black,purple], Xs).
Xs = [green,red,blue,yellow,brown,orange,black]. % succeeds deterministically
对于更一般的问题,我们也能得到合乎逻辑的答案吗

?- list_uniqs([A,B,A], []). A=B ; false. ?- list_uniqs([A,B,A], [_]). dif(A,B). ?- list_uniqs([A,B,A], [_,_]). false. ?- list_uniqs([A,B,A], Xs). Xs = [] , A=B ; Xs = [B], dif(A,B). ?-列表_uniq([A,B,A],])。 A=B ; 错。 ?列出所有单位([A,B,A],[U])。 dif(A,B)。 ?列出所有单位([A,B,A],[u,[u])。 错。 ?-列表_uniq([A,B,A],Xs)。 Xs=[],A=B ; Xs=[B],dif(A,B)。 对!!来点更一般的怎么样

?- list_uniqs([A,B,C],Xs). Xs = [] , A=B , B=C ; Xs = [C] , A=B , dif(B,C) ; Xs = [B] , A=C , dif(B,C) ; Xs = [A] , dif(A,C), B=C ; Xs = [A,B,C], dif(A,B), dif(A,C), dif(B,C). ?列表_uniq([A,B,C],Xs)。 Xs=[],A=B,B=C ; Xs=[C],A=B,dif(B,C) ; Xs=[B],A=C,dif(B,C) ; Xs=[A],dif(A,C),B=C ; Xs=[A,B,C],dif(A,B),dif(A,C),dif(B,C)。 它起作用了

更简单(且不纯:-)


您的
my\u delete\u worker/3
谓词将删除元素,即使它是列表中唯一的元素。例如,
my\u delete\u worker([a,b,c],b,R)。
产生,
R=[a,c]
。“我以为这就是你想要避免的?”重复。请看我更简单的答案。 ?- list_uniqs([A,B,A], []). A=B ; false. ?- list_uniqs([A,B,A], [_]). dif(A,B). ?- list_uniqs([A,B,A], [_,_]). false. ?- list_uniqs([A,B,A], Xs). Xs = [] , A=B ; Xs = [B], dif(A,B). ?- list_uniqs([A,B,C],Xs). Xs = [] , A=B , B=C ; Xs = [C] , A=B , dif(B,C) ; Xs = [B] , A=C , dif(B,C) ; Xs = [A] , dif(A,C), B=C ; Xs = [A,B,C], dif(A,B), dif(A,C), dif(B,C).
singletons(Xs, Zs) :- findall(X, (select(X,Xs,Ys), \+memberchk(X,Ys)), Zs).