Prolog:删除具有非实例化值的列表成员

Prolog: remove member of list with non-instantiated values

我想删除列表中某个元素的所有出现,类似于 this,但在我的例子中,列表可能包含非实例化变量。例如:

delMember(z, [A,B,A,z], L).
L = [A, B, A];
false.

delMember(A, [A, B, A, z], L).
L = [B,z];
false.

我尝试将 delMember 定义如下:

delMember(_, [], []).
delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y).
delMember(X, [T|Xs], [T|Y]) :- X \== T, delMember(X, Xs, Y).

根据这个定义,我得到的最后结果是正确的,但它仍在尝试实例化之前的变量。

?- delMember(A, [A,B,A,z], R).
A = B, B = z,
R = [] ;
A = B,
R = [z] ;
A = z,
R = [B] ;
R = [B, z] ;

有什么想法吗???

如果您查看第二个谓词从句:

delMember(X, [X|Xs], Y) :- delMember(X, Xs, Y).

第一个和第二个参数中的 X 正在统一。这会导致您在进行查询时观察到的结果。您需要应用与第三个子句中相同的运算符。所以你的完整谓词(有一些稍微改变的变量名称更传统)看起来像:

delMember(_, [], []).
delMember(X, [X1|Xs], Ys) :- X == X1, delMember(X, Xs, Ys).
delMember(X, [X1|Xs], [X1|Ys]) :- X \== X1, delMember(X, Xs, Ys).