Prolog allMember功能

时间:2014-10-06 02:06:27

标签: prolog

我正在尝试编写一个接收两个列表的函数,如果第一个列表中的每个元素在第二个列表中至少出现一次,则返回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).

2 个答案:

答案 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).