Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 是否从列表中删除重复项,但不在SWI Prolog中返回两个相同的结果?_List_Prolog_Duplicates - Fatal编程技术网

List 是否从列表中删除重复项,但不在SWI Prolog中返回两个相同的结果?

List 是否从列表中删除重复项,但不在SWI Prolog中返回两个相同的结果?,list,prolog,duplicates,List,Prolog,Duplicates,我写这个谓词是为了从列表中删除replicate,但是当我测试它时 duplicate([],[]). duplicate([A|B],[A|B1]) :- not(member(A,B)), duplicate(B,B1). duplicate([A|B],List) :- member(A,B), duplicate(B,List). 有没有办法只保留一个结果,而不是两个相同的结果?(因此它将只返回一个列表) 此外,我不允许使用修改回溯搜索的运算符,例如剪切运算符!,否定运算符not、+,

我写这个谓词是为了从列表中删除replicate,但是当我测试它时

duplicate([],[]).
duplicate([A|B],[A|B1]) :- not(member(A,B)), duplicate(B,B1).
duplicate([A|B],List) :- member(A,B), duplicate(B,List).
有没有办法只保留一个结果,而不是两个相同的结果?(因此它将只返回一个列表)

此外,我不允许使用修改回溯搜索的运算符,例如剪切运算符!,否定运算符not、+,或带有->和的if-then-else运算符


如果有人能帮助我,我将不胜感激D

这里有一种方法可以删除所有重复项,虽然不是最有效的方法,但我认为很容易理解其意图

?- duplicate([a,b,c,a,d,c,b,a,e,f],N).
N = [d, c, b, a, e, f] ;
N = [d, c, b, a, e, f] ;
false.
如果您打算将列表编成一组:

rm_duplicates(In, Out) :-
    exclude(has_duplicate(In), In, Out).

has_duplicate(List, Case) :-
    dif(I, J),
    nth0(I, List, Case),
    nth0(J, List, Case).

它被记录为:

收到多个答案的实际原因是目标
成员(A,As)
。它为
As
中的重复项生成多个答案

list_to_set(List, Set).
有几种解决办法

memberchk/2
一次/1
memberchk/2
定义为

?-  member(a, [a,a]).
    true
;   true.
这将删除备选答案。但是,它也可能会删除其他有效的解决方案。考虑:

memberchk(X, Xs) :-
   once(member(X, Xs)).
因此
memberchk/2
对精确的实例化非常敏感,这使得它成为一个非常脆弱、不纯净的谓词

但它有一个优点:它只针对一个问题给出了一个答案

?-        memberchk(X, [a,b]), b = X.
false.
?- b = X, memberchk(X, [a,b]), b = X.
b = X.
所以理想的定义是既纯粹又坚持第一个元素。进入

memberd/2
在此定义中,递归规则仅在列表元素不同时才具有相关性。因此,此规则永远不会应用于
成员d(a[a,a,a])

您定义中的另一个问题是
not(成员(A,B))
,如果
A
B
被充分实例化,则该问题只会按预期的方式运行。您的定义因以下原因而失败:
重复([a,X],[a,b])。
尽管有一个解决方案:
X=b

而不是用新的方法来取代它

P>可选的,如果您对最有效的解决方案感兴趣,请考虑<代码>库(RIF)< /代码> 对于 和 这导致:

memberd(X, [X|_Ys]).
memberd(X, [Y|Ys]) :-
   dif(X, Y),
   memberd(X, Ys).

使用
memberchk/2
代替
member/2
。也可以使用
\+
而不是
而不是/1
,因为前者是ISO Prolog,后者是不推荐使用的。另外,仅供参考,只有剪切修改了搜索过程。请注意
排除/3
有一个隐式剪切,它会生成错误的答案,例如:
B=B,rmu重复([a,B],Cs)。
成功,而
rmu重复([a,B],Cs).
failsOh,谢谢,我用memberchk解决了这个问题。再次感谢您的回答!
memberd(X, [X|_Ys]).
memberd(X, [Y|Ys]) :-
   dif(X, Y),
   memberd(X, Ys).
list_nub([], []).
list_nub([X|Xs], Ys0) :-
   if_(memberd_t(X, Xs),  Ys0 = Ys1, Ys0 = [X|Ys1]),
   list_nub(Xs, Ys1).