1

我是 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))is alwaysfalse并且在绑定部分只有XandXs和 never Y。非常感谢任何建议!谢谢你。

更新

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

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

但我不太确定为什么它现在可以工作......在第 3 次occ我改变了_Ywith [].. 但为什么它会改变结果?

4

1 回答 1

2

在这个答案中,我们将 tpartition/4if_/3and结合使用(=)/3

我们list_duplicateset/2这样定义:

列表重复集([],[])。
list_duplicateset([E|Xs0], Ys0) :-
   tpartition ( = (E), Xs0, Es, Xs),
    if_ (Es = [],
       Ys0 = Ys,
       Ys0 = [E|Ys]),
   list_duplicateset(Xs, Ys)。

首先,我们运行一个从这个答案中提取的示例查询,用于类似问题

?- 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 = [].

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

于 2015-11-26T16:01:53.720 回答