List 使用多个列表元素的一个匹配项填充列表

List 使用多个列表元素的一个匹配项填充列表,list,prolog,prolog-dif,meta-predicate,List,Prolog,Prolog Dif,Meta Predicate,我不熟悉Prolog,我正在努力理解它 我从一些简单的程序开始,这个程序应该: 检查列表的其余部分是否包含元素 如果错误,什么也不做 如果为TRUE,则将其添加到第二个列表中。(第二个列表中只应添加一个字符) 一些预期结果的例子: ?- occ([a,b,c,a,a,b,e,f,g], Y). Y = [a,b]. ?- occ([a,a,a,a,a], Y). Y = [a]. ?- occ([a,b,c,d,e,f,g], Y). Y = []. 这是我写的代码,但我有一些问题

我不熟悉Prolog,我正在努力理解它

我从一些简单的程序开始,这个程序应该:

  • 检查列表的其余部分是否包含元素
    • 如果错误,什么也不做
    • 如果为TRUE,则将其添加到第二个列表中。(第二个列表中只应添加一个字符)
一些预期结果的例子:

?- occ([a,b,c,a,a,b,e,f,g], Y).
Y = [a,b].

?- occ([a,a,a,a,a], Y).
Y = [a].

?- occ([a,b,c,d,e,f,g], Y).
Y = [].
这是我写的代码,但我有一些问题(它总是返回
true

我尝试使用调试器,发现
not(成员(X,Y))
总是
false
,在绑定部分中只有
X
Xs
,而从不
Y
。任何建议都将不胜感激!多谢各位

更新

我想我已经解决了,代码如下:

occ([],[]).
occ([X|Xs],[X|Y]) :-
   occ(Xs,Y),
   member(X,Xs),
   not(member(X,Y)),
   !.
occ([_X|_Xs],[]).
但我真的不知道为什么它现在起作用了。。。在第三次
occ
中,我用
[]
更改了
\Y
。。 但是为什么它会改变结果呢?

在这个答案中,我们结合and使用

我们这样定义
list\u duplicateset/2

list_duplicateset([], []). list_duplicateset([E|Xs0], Ys0) :- tpartition(=(E), Xs0, Es, Xs), if_(Es = [], Ys0 = Ys, Ys0 = [E|Ys]), list_duplicateset(Xs, Ys). 接下来,让我们运行OP给出的查询:

?- list_duplicateset([a,b,c,a,a,b,e,f,g], Xs).
Xs = [a, b].

?- list_duplicateset([a,a,a,a,a], Xs).
Xs = [a].

?- list_duplicateset([a,b,c,d,e,f,g], Xs).
Xs = [].
请注意,上面显示的所有查询
给出期望的答案,然后决定性地成功。

谓词总是返回true,因为您有两个子句,它们一起将接受任何列表参数并成功<代码>occ([],_Y)。将始终成功,无论第二个参数是什么,如果第一个参数是空列表
[]
。如果第一个参数是至少一个元素的列表,则无论第二个参数是什么,都将始终成功。您要做的是确保每个子句在表达有关其参数的有效规则时都是有意义的。我尝试更改代码,但未能达到预期的效果。。。你能再帮我一点忙吗?我想我遗漏了一些东西。如果你用最新的更改编辑你的问题,以了解你当前的想法,这可能会有所帮助。我更新了我的问题,我可能解决了它。。。虽然我真的不明白为什么它现在起作用了。。。你能给我解释一下吗?编辑2:我不确定它是否总是有效:\n我认为它仍然存在问题。您的第三条规则基本上是说,任何非空列表都应该产生一个空列表,这不应该是真的。你能解释一下你为什么有这个规则吗?你所掌握的任何规则都应该能够用语言来描述。这将帮助您理解您的解决方案。你的第一条规则是,空列表的结果就是空列表,这当然是有意义的。你的第二条规则说,
[X | Y]
[X | Xs]
的结果,如果
Y
Xs
的结果,
X
Xs
的成员,而
X
不是
Y
的成员。
?- list_duplicateset([1,2,2,3,4,5,7,6,7], Xs). 
Xs = [2,7].
?- list_duplicateset([a,b,c,a,a,b,e,f,g], Xs).
Xs = [a, b].

?- list_duplicateset([a,a,a,a,a], Xs).
Xs = [a].

?- list_duplicateset([a,b,c,d,e,f,g], Xs).
Xs = [].