gnu Prolog powerset modification

余生颓废 提交于 2019-11-27 16:10:48

How about

powerset(L, [H|T]):-
  append([H|T], _, L).
powerset([_|L], P):-
  powerset(L, P).

You want all subsequences substrings (definition). Grammars (DCGs) are best for this:


seq([]) -->
   [].
seq([E|Es]) -->
   [E],
   seq(Es).

... --> [] | [_], ... .

?- Es = [_|_], phrase((..., seq(Es), ...), [A,B,C]).
Es = [A] ;
Es = [A, B] ;
Es = [A, B, C] ;
Es = [B] ;
Es = [B, C] ;
Es = [C] ;
false.

(SWI-Prolog)

I know this an old post, but I'm not gonna update it for no reasons. the answer which is accepted with all the respect, generates all subsets separably, and does not generate a powerset.

a few days ago I was trying to implement a powerSet/2 predicate, without use of built-in predicate bagof/2. but even with bagof/2 and setof/2 it's not very easy problem for beginners (generating all subset separably is another problem and much easier). so after implementing the solution I thought it's better to put it here in order to prevent people who are searching for this topic from mistakes.

My solution (without bagof/2)

generate(X, [Y], [[X| Y]]).

generate(X, S, P) :-
        S = [H| T],
        append([X], H, Temp),
        generate(X, T, Rest),
        append([Temp], Rest, P), !.

powerSet([], [[]]).

powerSet(Set, P) :-
        Set = [H| T],
        powerSet(T, PsT),
        generate(H, PsT, Ps),
%       write('trying to push '), print(H), write(' to '),
%       write('all elements of powerset of '), print(T), write(' which is '),
%       print(PsT), nl,
%       write('and the result is '), print(Ps), nl, nl,
        append(Ps, PsT, P), !.

code will be understood if consulted with the commented lines.

another solution is available here which uses built-in predicate bagof/3.

probably it would be more helpful now.

How about this:

powerset(A,B):-
    append(A,_,B);
    append(_,A,B).

test():-
    setof(X,powerset(X,[1,2,3]),L),
    writeln(L).
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!