2014-10-06 36 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).