在课堂上,我们回顾了我的老师给出的 subset_of/2 谓词如下:
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 的子集(但不是通过使用长度/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).
我不是要求正确的代码来解决这个问题,而只是朝着正确的方向推进,这样我就可以继续尝试解决这个问题。这是我第一次使用声明性语言,我很困惑。