确定第一个列表的所有成员是否都是第二个列表的成员

时间:2019-02-22 03:44:30

标签: list prolog

我无法启动这个Prolog程序,该程序需要两个列表,如果第一个列表中的所有成员都是第二个列表的成员,则返回true,否则返回false。

示例:

?- members([a, c], [a, b, c, d])
true
?- members([d, a, c, a], [a, b, c, d, e])
true
?- members([b, e], [a, b, c, d])
false
?- members([], [a, b, c, d])
true

我该怎么做?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

您可以在这种问题上使用maplist,因为它遵循标准的递归列表遍历:

mem(L, X) :- memberchk(X, L).
subset(S, L) :- maplist(mem(L), S).

结果:

| ?- subset([a,c], [a,b,c,d]).

yes
| ?- subset([c,a], [a,b,c,d]).

yes
| ?- subset([e], [a,b,c,d]).

no
| ?- subset([], [a,b,c,d]).

yes
| ?- subset(S, [a,b,c,d]), S=[_|_].

S = [a] ? ;

S = [a,a] ? ;

S = [a,a,a] ? ;
...

请注意,原始问题定义并不排除子集可以具有超集中重复元素的情况。如果要将子集的元素数限制为小于或等于超集,则可以使用select/3

subset([], _).
subset([X|Xs], L) :-
    select(X, L, L1),
    subset(Xs, L1).

结果:

| ?- subset([a,c], [a,b,c,d,e]).

true ? ;

no
| ?- subset([a,f], [a,b,c,d,e]).

no
| ?- subset([a,a], [a,b,c,d,e]).

no
| ?- subset(S, [a,b,c]), S=[_|_].

S = [a] ? ;

S = [a,b] ? ;

S = [a,b,c] ? ;

S = [a,c] ? ;

S = [a,c,b] ? ;

S = [b] ? ;

S = [b,a] ? ;
...

S = [c,b] ? ;

S = [c,b,a] ? ;

no

您会注意到,列表[c,b,a]在Prolog中被视为与[a,b,c]不同的列表,因此它是一个单独的解决方案。如果您想使列表真正按集合表现,那是另一种解决方案。

答案 1 :(得分:0)

“我们什么也没尝试,我们全都没主意了”

我建议您找到一个可以执行此操作的谓词,然后查看其实现。

$ swipl
?- subset([a, c], [a, b, c, d]).
true.

?- subset([d, a, c, a], [a, b, c, d, e]).
true.

?- subset([b, e], [a, b, c, d]).
false.

?- subset([], [a, b, c, d]).
true.

在此处记录:http://www.swi-prolog.org/pldoc/doc_for?object=subset/2

您可以点击带有冒号和破折号的黄色小圆圈以查看其实现方式:http://www.swi-prolog.org/pldoc/doc/SWI/library/lists.pl?show=src#subset/2

713 subset([], _) :- !.
714 subset([E|R], Set) :-
715     memberchk(E, Set),
716     subset(R, Set).

此定义与以下内容大致相同:

maplist([M]>>memberchk(M, Set), Subset)

此定义总是成功或失败一次。这是设计使然。

它也可以这样实现:

maplist([M]>>member(M, Set), Subset)

它的行为就像评论中的建议:

?- maplist([M]>>member(M, [a,b]), Subset).
Subset = [] ;
Subset = [a] ;
Subset = [a, a] ;
Subset = [a, a, a] ;
Subset = [a, a, a, a] .

?- length(Subset, _), maplist([M]>>member(M, [a,b]), Subset).
Subset = [] ;
Subset = [a] ;
Subset = [b] ;
Subset = [a, a] ;
Subset = [a, b] ;
Subset = [b, a] ;
Subset = [b, b] ;
Subset = [a, a, a] ;
Subset = [a, a, b] .