仅包含一个多个列表元素的列表填充列表

时间:2015-11-26 12:51:17

标签: list prolog prolog-dif

我是Prolog的新手,我正在努力理解它。

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

  • 检查列表的其余部分是否包含元素
    • 如果FALSE什么都不做
    • 如果为TRUE,则将其添加到第二个列表中。 (只应在第二个列表中添加一次char。)

预期结果的一些例子:

?- 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)。

occ([],[]).
occ([],_Y).
occ([X|Xs],[X|Y]) :-
   occ(Xs,Y),
   member(X,Xs),
   not(member(X,Y)),
   !.
occ([_X|_Xs],_Y).

我尝试使用调试器,但我发现not(member(X,Y))始终为false,而在绑定部分中只有XXs且从不Y }。任何建议都非常感谢!谢谢。

更新

我想我已经解决了,这里是代码:

occ([],[]).
occ([X|Xs],[X|Y]) :-
   occ(Xs,Y),
   member(X,Xs),
   not(member(X,Y)),
   !.
occ([_X|_Xs],[]).

但我现在还不确定为什么会有效......在第3 occ我用_Y更改了[]。 但为什么会改变结果?

1 个答案:

答案 0 :(得分:2)

在此回答中,我们将 tpartition/4if_/3(=)/3结合使用。

我们这样定义list_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).

首先,我们运行从this answer to a similar question获取的示例查询:

?- list_duplicateset([1,2,2,3,4,5,7,6,7], Xs). 
Xs = [2,7].

接下来,让我们运行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 = [].

请注意上面提到的所有查询 给出预期答案,确定性地成功