2014-10-06 57 views
0

我正在尝试编写一个函数,它接受两个列表并返回true,如果第一个列表中的每个元素至少在第二个列表中出现一次。例如:Prolog allMember函数

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

都列表排序? – 2014-10-06 06:11:15

+0

@CommuSoft这是一个很好的问题,但从他的示例输出来判断,可能不是。尽管如此,仍然需要澄清。 – 2014-10-06 06:25:55

回答

1

描述谓词的方式,实在是小巫见大巫:

my_subset([], _Set) :- !. 
my_subset([X|Xs], Set) :- 
    memberchk(X, Set), 
    my_subset(Xs, Set). 

这也是SWI-Prolog的标准库的implementation,例如。

您的代码,但是,说点别的:

all_member(L1, L2)为真,当L1为L2的元素的组合,与长度可达(含)L2的长度。”

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 in all_member/2给出了第一个列表的所有有效长度。 的all_member_1/2为您提供了第二个列表中元素的所有可能组合。

如果您知道您希望使用谓词的可行性,这可能不是一个好的解决方案。尝试例如最普通的查询,?- all_member(L1, L2)。你需要更具体地了解这一点。

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