我现在正在学习Prolog,递归思考对我来说很难。
我有两个列表,例如L1=[1,2,3]
和L2=[3,1,2]
我应该检查L1
L2
的所有元素
所以allMembers(L1,L2).
应该返回true
而allMembers(L1,[2,3,4]).
应该返回false
,因为4
中没有L1
我认为有可能获得一个列表的头部并返回true如果它在另一个列表中找到该元素(通过将其拆分直到列表只包含一个项目),但我不知道如何在Prolog中做到这一点。
如果能帮助我加快速度(?)
,那就太好了我在这里发现了类似的问题,但找不到我特定问题的答案:/
编辑:
我现在有:
isMemberOf(X,[X|_]).
isMemberOf(X,[_|T]):- member(X,T).
我需要将其用于L1
到L2
答案 0 :(得分:2)
要解决您的子问题:如果member(A,B)
是列表A
的成员,则B
为真。
答案 1 :(得分:2)
定义它的最简单方法可能是:
% contained_in(L1, L2) succeeds if all elements of L1 are contained in L2
contained_in(L1, L2) :- maplist(contains(L2), L1).
contains(L, X) :- member(X, L).
maplist/2
会将contains(L2)
应用于L1
的每个元素,并且如果每次调用都成功,则会成功。 contains/2
与member/2
类似,但会将参数按照使其与maplist
一起使用的顺序排列。
答案 2 :(得分:2)
使用事实上的标准谓词的快速解决方案:
all_from_first_in_second(List1, List2) :-
forall(member(Element,List1), member(Element,List2)).
答案 3 :(得分:1)
只需使用list_permuted/2
,就像这样:
?- list_permuted([1,2,3],[3,1,2]).
true.
请注意,list_permuted/2
要求两个列表具有相同数量的相同项目!
答案 4 :(得分:0)
这解决了只有自定义谓词的问题:
% allMembers(L1,L2) checks if all elements of L1 are available in L2
% solve the sub problem
isMemberOf(X,[X|_]).
isMemberOf(X,[_|T]):- isMemberOf(X,T).
% iterate through 'L1' and ask if the member exists in 'L2'
allMembers([],_).
allMembers([H|T],L):- allMembers(T,L), isMemberOf(H,L).