Prolog 序言-从列表中删除成员

Prolog 序言-从列表中删除成员,prolog,Prolog,我是prolog新手,我写了这段代码,假设返回一个列表的所有子列表,其中没有一些成员 contained(X, Y) :- member(M, Y). select(M, Y, X). 我键入的查询是: contained(X, [1,2]) . 预期结果是: [1], [2] 我得到的结果是: true, true 我遗漏了什么?您犯的错误是在成员(M,Y)的末尾写了一个点()。这意味着Prolog认为您编写了: contained(X, Y) :- member(M, Y).

我是prolog新手,我写了这段代码,假设返回一个列表的所有子列表,其中没有一些成员

contained(X, Y) :-
member(M, Y).
select(M, Y, X).
我键入的查询是:

contained(X, [1,2]) .
预期结果是:

[1],
[2]
我得到的结果是:

true,
true

我遗漏了什么?

您犯的错误是在
成员(M,Y)
的末尾写了一个点(
)。这意味着Prolog认为您编写了:

contained(X, Y) :-
    member(M, Y).  %% notice the dot (.) here
select(M, Y, X).
也就是说,这里不需要
member/2
。事实上,通过使用member,如果列表包含重复的值,将导致多次生成相同的列表

您只需在此处与项目上的通配符(
\uu
)一起使用即可删除:

contained(X, Y) :-
    select(_, Y, X).

你明白
select/3
的作用吗?它说:“当删除元素后的List1生成List2时,这是真的。如果List1的最后一个元素被选中,这个实现是确定的。”…这难道不意味着删除后X将成为该列表吗?也许,还需要考虑一下在不使用库谓词的情况下如何编写这个列表。您可以使用三个简单的规则(一个基本情况,两个递归情况)来完成它。@ChenDoytshman注意到Prolog可能给了您很多单例变量警告。从现在起,您应该将这些错误视为停止我正在做的事情并修复致命错误,因为第2行的m和第3行的m、Y和X可能都有一个错误,这表明某些内容肯定没有按照您预期的方式进行解析。
contained(X, Y) :-
    select(_, Y, X).
contained(T, [_|T]).
contained([H|T1], [H|T2]) :-
    contained(T1, T2).