我试图从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(无论我是否输入包含唯一变量的列表)。
任何人对我做错了什么有任何想法或建议?
答案 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).
所以,我认为你对何时以及为什么你应该有多个条款有点混淆,我认为你选择变量名可能会让自己的生活更加艰难。但这只是我的猜测。
希望这有帮助!