如何检查列表2是否包含所有列表1s元素?

时间:2017-09-14 16:49:22

标签: prolog

我对Prolog很新。我遇到了这个问题: 如果我有两个列表,如何检查列表1是否包含第二个列表的所有元素,但它们不必相等。所以列表2可能包含更多元素。

我知道我可以使用member/2来检查某个元素是否在列表中。但是在我检查后,我不知道如何不包括这两个列表中的这些成员。例如:
如果我有列表A = [a,b,c,a]并列出B = [a,b,c,d,e],我首先检查列表A中的第一个'a'是否在列表B中。显然这会返回一个True,但如果我检查最后一个'a'从列表A中,我应该返回一个False,因为列表A有2个'a'而B只有1个,而我返回True。我真的不知道如何解决这个问题。

如果有人可以帮助我,我真的很感激:) 谢谢!

编辑:更多地解释我的问题

1 个答案:

答案 0 :(得分:0)

select/3完全符合我们的要求:

is_sublist([], []).
is_sublist([], [_|_]).
is_sublist([H|T], L) :-
    once(select(H, L, L2)),
    is_sublist(T, L2).

我们将其包装在once/1中,以避免在元素多次出现的情况下出现多余的成功。

注意:您可以移除once/1以获得更多工作行为:

?- is_sublist(Z,[a,b,c]).          % Without once
Z = [] ;
Z = [a] ;
Z = [a, b] ;
Z = [a, b, c] ;
Z = [a, c] ;
Z = [a, c, b] ;
Z = [b] ;
Z = [b, a] ;
Z = [b, a, c] ;
Z = [b, c] ;
Z = [b, c, a] ;
Z = [c] ;
Z = [c, a] ;
Z = [c, a, b] ;
Z = [c, b] ;
Z = [c, b, a] ;
false.

这不会在相反的方向列举所有可能的答案,所以并非一切都是完美的:

?- is_sublist([a,b],Z).             % Without once
Z = [a, b] ;
Z = [a, b, _886|_888] ;
Z = [a, _880, b|_888] ;
Z = [a, _880, _892, b|_900] ;
Z = [a, _880, _892, _904, b|_912]
…