我正在尝试编写一个接收两个列表的函数,如果第一个列表中的每个元素在第二个列表中至少出现一次,则返回true。示例:
allMember(X, [a,b]).
X = [] ;
X = [a] ;
X = [b] ;
X = [a a] ;
X = [a b] ;
X = [b a] ;
X = [b b] ;
false.
问题是在决赛之后;程序循环无限地检查每个可能的列表。我该如何解决这个问题?
allmember([], _).
allmember([F|R], L2) :- length([F|R], Len1),
length(L2, Len2),
Len1 =< Len2,
member(F, L2),
allmember(R, L2).
答案 0 :(得分:1)
描述谓词的方式,它是微不足道的:
my_subset([], _Set) :- !.
my_subset([X|Xs], Set) :-
memberchk(X, Set),
my_subset(Xs, Set).
例如,这也是SWI-Prolog标准库中的implementation。
然而,您的代码还说了一些其他内容:
&#34; all_member(L1, L2)
如果L1是L2元素的组合,长度达到(包括)L2的长度,则为真。&#34;
all_member(L1, L2) :-
length(L2, Max_len),
between(0, Max_len, Len),
length(L1, Len),
all_member_1(L1, L2).
all_member_1([], _).
all_member_1([X|Xs], L) :-
member(X, L),
all_member_1(Xs, L).
这里,首先获取最大长度(第二个参数的总长度),然后枚举长度为0到最大长度的列表,然后将member/2
应用于每个列表的每个元素。
between/3
中的all_member/2
为您提供第一个列表的所有有效长度。 member/2
中的all_member_1/2
为您提供了第二个列表中所有可能的元素组合。
如果您知道如何使用谓词,那么这可能不是一个足够好的解决方案。例如,尝试最常见的查询?- all_member(L1, L2)
。你需要对此更加具体。
答案 1 :(得分:0)
我使用以下代码解决了问题:
find( L, L2, I) :- length(L2, Length2),
range(0, Length2, PossI),
member(I, PossI),
find1(L, L2, I).
find1([F1|[]], [F1|_], 0).
find1([F1|R1], [F1|R2], 0) :- find(R1, R2, 0).
find1(L1, [_|R2], I) :- M is (I-1),
find(L1, R2, M).