想象一下有一个像 L = [1, 4, _, 5, _]
这样的列表
如果我想检查 4
是否是这个列表的成员,我可以这样做:member(4, L)
。这将返回 True,因为此列表中有一个 4
。但是,它使用 member/2 对我检查的每个元素返回 true。这当然会发生,因为匿名变量可以与任何东西匹配。所以它总是返回 True。我想知道是否有一种方法可以从 L
列表中删除所有匿名变量。所以 NewList
将是 [1, 4, 5]
。
最佳答案
除了从列表中删除变量然后使用 member/2
之外,您还可以选择实现自己的谓词来描述非-可变元素:
nonvarmember(X,[Y|_]) :-
nonvar(Y), % only try to unify with X if Y is not a variable
X=Y.
nonvarmember(X,[_Y|Ys]) :-
nonvarmember(X,Ys).
现在让我们看看这个谓词是如何工作的:
?- nonvarmember(4,[1,4,_,5,_]).
true ;
false.
?- nonvarmember(4,[1,_,_,5,_]).
false.
?- nonvarmember(4,[1,4,_,5,_,Z]).
true ;
false.
但是,第一个参数仍然可以是一个变量:
?- nonvarmember(X,[1,4,_,5,_,Z]).
X = 1 ;
X = 4 ;
X = 5 ;
false.
?- nonvarmember(X,[_,_,_]).
false.
但是请注意,无论您是先从列表中删除可变元素然后使用 member/2
还是使用 nonvarmember/2
,都没有关系,您遇到以下问题:在您检查成员资格后实例化的列表元素未被考虑在内,因此可能导致不正确的答案。下面的例子说明了这个问题:
?- A=4, nonvarmember(4,[A,B,C]).
A = 4 ;
false.
?- nonvarmember(4,[A,B,C]), A=4.
false.
关于prolog - 如何使用匿名变量检查列表中的某些元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46632751/