我正在尝试返回列表中的不同项目。我提出了以下代码。使用member(X,Y)检查列表的成员时,我似乎遇到了问题,并且陷入了无限循环。
get_unique(Y, [H|T]) :-
memberchk(H, Y)-> get_unique(Y, T) ; get_unique([H|T], T).
get_unique(_, []) :- true.
final_list(X, L) :-
get_unique(Y, L), member(X,Y).
有两种输入方式:
?- final_list(dog,[dog,cat,bat,dog]).
true;
true;
true;
true;
(infinitely)
在这种情况下,我希望只是
true;
false.
另一种输入方式:
?- final_list(X,[dog,cat,bat,dog]).
X = dog;
X = cat;
X = bat;
true ;
true ;
true ;
true ;
true ;
true ;
(infinitely)
在这种情况下,我希望只是
X = dog;
X = cat;
X = bat;
false.
我尝试进行一些调试,我想我可以看到member(X,Y)正在生成无限循环-跟踪下面显示的步骤。我不知道如何阻止它,这样成员一旦返回bat就停止检查。
X = bat ;
Redo: (9) lists:member(_6632, [dog, cat, bat|_6882]) ? creep
Exit: (9) lists:member(_6632, [dog, cat, bat, _6632|_6888]) ? creep
Exit: (8) final_list(_6632, [dog, cat, bat, dog]) ? creep
true ;
Redo: (9) lists:member(_6632, [dog, cat, bat, _6886|_6888]) ? creep
Exit: (9) lists:member(_6632, [dog, cat, bat, _6886, _6632|_6894]) ? creep
Exit: (8) final_list(_6632, [dog, cat, bat, dog]) ? creep
true ;
Redo: (9) lists:member(_6632, [dog, cat, bat, _6886, _6892|_6894]) ? creep
Exit: (9) lists:member(_6632, [dog, cat, bat, _6886, _6892, _6632|_6900]) ? creep
Exit: (8) final_list(_6632, [dog, cat, bat, dog]) ? creep
true ;
Redo: (9) lists:member(_6632, [dog, cat, bat, _6886, _6892, _6898|_6900]) ? creep
Exit: (9) lists:member(_6632, [dog, cat, bat, _6886, _6892, _6898, _6632|...]) ? creep
Exit: (8) final_list(_6632, [dog, cat, bat, dog]) ? creep
true ;
谢谢!
答案 0 :(得分:2)
单独尝试get_unique/2
:
?- get_unique(Y,[dog,cat,bat,dog]).
Y = [dog,cat,bat|_A].
% ^^^
因此,Y
只是一个部分列表,而不是(真实)列表。它包含具有三个或更多元素的所有列表。
第二个子句应读为get_unique([], []).
,以避免出现此问题。而且第一个也需要重新排列:
get_unique(Y, [H|T]) :-
( memberchk(H, T) -> get_unique(Y, T) ; Y = [H|Y1], get_unique(Y1, T) ).
% ^^ ^^^^^^^^^^ ^^
get_unique([], []).
但是,您的定义仍然有一些奇怪的假设:
?- final_list(X,[dog,Cat]).
X = dog, Cat = dog.
因此它迫使变量成为一个特定值。
除了重新考虑member/2
之外,没有解决之道。有关干净的解决方案,请参见this answer。这是memberd/2
产生的答案:
?- memberd(X,[dog,Cat]).
X = dog
; X = Cat, dif(Cat,dog)
; false.
所以答案是:X = dog
和以前一样,X = Cat
,但前提是Cat
与dog
不同。