【发布时间】:2012-10-28 18:13:39
【问题描述】:
我是 Prolog 的新手,在检查两个列表是否具有完全相同的元素时遇到问题。元素可能有不同的顺序。我有这个代码:
myremove(X, [X|T], T).
myremove(X, [H|T], [H|R]) :-
myremove(X, T, R).
same_elements([], []).
same_elements([H1|T1], L2) :-
myremove(H1, L2, Nl2),
same_elements(T1, Nl2).
它的工作原理只是
?- same_elements([b,c,a], X).
在返回第一个结果后导致内存不足错误。因此,我尝试通过检查列表的长度是否相等并检查 H1 是否是 L2 的成员来缩小结果集:
mylength([], 0).
mylength([_|T], R) :-
mylength(T, Nr),
R is Nr+1.
mymember(X, [X|_]).
mymember(X, [_|T]) :-
mymember(X, T).
same_elements([], []).
same_elements([H1|T1], L2) :-
mylength([H1|T1], X),
mylength(L2, Y),
Y = X,
mymember(H1, L2),
myremove(H1, L2, Nl2),
same_elements(T1, Nl2).
现在两个
?- same_elements([b,c,a], X).
?- same_elements(X, [b,c,a]).
返回所有结果,但最后它们只是挂起。有一个更好的方法吗?
【问题讨论】:
-
你可以使用内置函数:
same_elements(X,Y) :- msort(X,S),msort(Y,S). -
我不知道为什么@false 说我的回答是一个糟糕的建议。现在我已经删除了。无论如何...你知道Prolog中cut有什么用吗?
-
当我尝试你的建议时,same_elements([b,c,a], X) 只返回一个结果,但我想要全部。
-
@chac:请看我的回答:您建议更改可见部分之外的内容。因此,您的切割将没有任何效果。
-
@chac:请看下面的故障切片。但要说得很清楚:通过在 myremove/3 中添加一个剪切,程序就像以前一样循环!
标签: list prolog non-termination failure-slice