从prolog中的列表中删除唯一元素

时间:2017-06-02 23:15:34

标签: prolog

我试图从Prolog中的列表中删除唯一元素。

输出应该类似于:

rem_Uniq(L1,L2).
rem_Uniq([L1|RL1], [L1|D]) :-
    member(L1,RL1),
    rem_Uniq(RL1,D).
rem_Uniq([L1|RL1], D) :-
    remove(L1[L1|RL1], O),
    rem_Uniq(O, D).

这是我目前的代码。

{{1}}

目前无论我做什么,它都会返回true(无论我是否输入包含唯一变量的列表)。

任何人对我做错了什么有任何想法或建议?

2 个答案:

答案 0 :(得分:1)

D是列表中仅出现一次的元素集。

在Prolog中"在列表中只出现一次的元素" 可以翻译

select(X, L, L_X),
\+member(X, L_X)

在Prolog中存在谓词,它收集具有特定属性 setof / 3 bagof / 3 的元素。

bagof收集所有元素,setof只保留一个元素。 所以你可以写

rem_uniq(In, Out) :-
    setof(X, In_X^(select(X, In, In_X),\+member(X, In_X)), Out).

<强> [编辑]

现在我们只想要列表中重复的元素。如果我删除列表中的其中一个元素,它将保留列表中相同值的其他元素,以便它可以在Prolog中翻译

select(X, In, In_X),
member(X, In_X)

(我们说选择(X,In,In_X),成员(X,In_X)成功)。 现在可以编写代码

rem_uniq(In, Out) :-
    setof(X, In_X^(select(X, In, In_X),member(X, In_X)), Out).

例如

?- rem_uniq([3,3,1,7,a,c,c],D).
D = [3,c].

请注意,如果没有可用元素,setof将失败

 ?- rem_uniq([3,1,7,a,c],D).
false.

答案 1 :(得分:0)

嗯,你的第一个问题是你的第一个问题:

rem_Uniq(L1,L2).

字面意思是“任何两件东西都是rem_Uniq彼此。”这就是在没有统一的情况下始终如一的原因。你可能意味着这个:

rem_Uniq([], []).

你的第二个问题是这不是有效的语法:

 remove(L1[L1|RL1], O),

具体来说,L1[L1|RL1],我不清楚你的意思。我认为你的意思是delete(L1, [L1|RL1], O)

现在,从算法上来说,我觉得你有点困惑。在第2节中,您在结果中将L1添加到D,也就是说,在知道RL 存在于RL1中并使用递归调用将其从D中删除之后,然后在子句#中3,你只需将它从[L1 | RL1]中删除即可制作O,然后从中删除uniques。

递归谓词的每个子句都应该代表一个你必须担心的情况。我真的不明白这些条款是什么意思。如果列表为空,则第一个应该是。第二个应该是列表不为空的情况。你似乎试图在这里做的事情是,在列表不是空的并且包含head元素的情况下,以及它不是空的并且不包含head元素的情况,但是具有或者没有那个元素对你的图书馆例程来说是(或者应该)没有意义。换句话说,在一个非空的递归情况下delete/3应该完全足以解决这个问题:

rem_uniq([], []).
rem_uniq([X|Xs], [X|UniqueXs]) :- 
  delete(X, Xs, XsWithoutX),
  rem_uniq(XsWithoutX, UniqueXs).

所以,我认为你对何时以及为什么你应该有多个条款有点混淆,我认为你选择变量名可能会让自己的生活更加艰难。但这只是我的猜测。

希望这有帮助!