在我們過了subset_of/2謂詞,我的老師給的類如下:序言:長度爲k的子集
subset_of([],[]).
subset_of([X|Xs],Zs):-subset_of(Xs,Ys),maybe_add(X,Ys,Zs).
maybe_add(_,Ys,Ys).
maybe_add(X,Ys,[X|Ys]).
subsets_of(Xs,Xss):-findall(Ys,subset_of(Xs,Ys),Xss).
然後,他問我們將其更改爲只給一些長度爲K的子集(但不通過使用length/2,直接找到遞歸定義)。我的第一個嘗試是將subset_of調用分解爲一個添加額外元素和一個不調用(而不是具有maybe_add調用)的元素,並跟蹤傳遞的列表長度並在最後檢查,但這沒有按計劃運作。
subset_of(K, 0, [],[]).
subset_of(K, Len, [X|Xs],Zs):-
L1 is Len - 1,
subset_of(K, L1, Xs, Zs),
L1 == K.
subset_of(K, Len, [X|Xs],Zs):-
L1 is Len - 1,
subset_of(K, L1, Xs,Ys),
do_add(X, Ys, Zs),
Len == K.
subsets_of(K,Xs,Xss):-
length(Xs, Len),
findall(Ys,subset_of(K, Len, Xs,Ys),Xss).
我不是要求正確的代碼來解決這個問題,但只是在正確的方向推,所以我可以不斷嘗試弄清楚。這是我第一次用聲明式的語言,我很困惑。
所以我想你所說的關於遞歸證明一個集合是另一個集合的一個k元素子集,這就是我所想到的。如果某物是k子集,那麼如果你把第一個元素取出,其餘的應該是一個k-1子集,它導致這個代碼ksubset_of(0,_,[])。 ksubset_of(K,[X |兩個X],ZS): - K1爲K1, \t \t \t ksubset_of(K1,XS,YS), \t \t \t ZS = [X | YS〕.' 但這隻會產生第一個,所以我不知道從哪裏去 – Stuart 2011-04-03 22:42:12
這是好的,你已經有兩個規則的候選人。然而,證明是不完整的,因此你錯過了第三條規則。附註:不要寫這樣的統一'Zs = [X |伊蘇]'。你應該把所有的'Zs'換成它的實際值。這不僅會更清晰,而且更高效。 – julkiewicz 2011-04-03 23:02:36
把它們想象成它們畢竟是有序的集合。這是因爲他們被要求你的證明不完整。這就是我想說的,我想說的。 – julkiewicz 2011-04-03 23:10:56