开发者

prolog: subsets of length k

in class we went over the subset_of/2 predicate that my teacher gave as follows:

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

He then asked us to change it to only give the subsets of some length K (but not by using length/2, by directly finding a recursive definition). My first attempt was to split up the subset_of call into one that adds the extra element and one that does not (instead of having the maybe_add call) and to keep track of the length of the list that was passed and check at the end, but this did not work as planned at all.

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,
        subs开发者_运维知识库et_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).

I am NOT asking for the correct code to solve this, but only a push in the right direction so I can keep trying to figure it out. This is my first time with a declarative languange and I am pretty confused.


If you don't want a direct answer, than I'd say that it can be done much simpler. I've got 3 rules in my solution. However I don't use this additional maybe_add formula or anything that resambles it. If you really need it, it can be used and it takes 5 arguments then - 3 input arguments and 2 output arguments. This reduces the number of rules for subset_of to only 2, just as in the original solution. They are quite similar after all.

Also watch out for repetitions. I think subset_of(0, _, []) as suggested in other answer may be a way that leads to repetitions. However there might be a correct solution that incorporates it, I'm not sure that there isn't.

Think of it as a proof of correctness. Say you wanted to prove recursively that one set is a K-element subset of another. How would you go about it. Look at the implications that you used. How can you turn them into Prolog rules?


Not using maybe_add seems like a good idea. However, you don't need two extra arguments: one will do. Your base clause would be

subset_of(0, _, []).

i.e., the empty set is a zero-element subset of anything. Of the two recursive clauses, one would look for K-1-element subsets, the other for K-sized subsets.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜