このディレクトリの索引
#  
#  部分集合の生成
#  
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  
%  非決定性に作っておいて、findallで収集する。
%  

全部分集合(_集合,_部分集合リスト) :-
        findall(_部分集合,(
                    部分集合(_集合,_部分集合)),
                _部分集合リスト).

部分集合(_集合,_部分集合) :-
        length(_集合,_要素数),
        for(1,N,_要素数),
        組合せ(_集合,N,_部分集合).


% ****** 組合せ / 3 ***

組合せ(X,1,[A]) :-
        member(A,X).
組合せ([A|Y],N,[A|X]) :-
        N > 1,
        M is N - 1,
        組合せ(Y,M,X).
組合せ([_|Y],N,A) :-
        N > 1,
        組合せ(Y,N,A).

%
% forループを使わない場合
% 

% ****** 全部分集合 / 2 *******

全部分集合(_集合,_部分集合リスト) :-
        length(_集合,_要素数),
        全部分集合(_要素数,_集合,_部分集合リスト).

% ***** 全部分集合 / 3 *******

全部分集合(0,_,[]) :- !.
全部分集合(N,_集合,LL) :-
        findall(L,組合せ(_集合,N,L),LL1),
        N_1 is N - 1,
        全部分集合(N_1,_集合,LL2),
        append(LL1,LL2,LL).

%%%%%%  for / 3 %%%%%%%%

for(S,N,E) :-
        E >= S,
        for_2(S,N,E).

for(S,N,E) :-
        E < S,
        for_1(S,N,E).

for_1(S,_,E) :- S < E,!,fail.
for_1(N,N,E).
for_1(S,N,E) :- S1 is S - 1,for_1(S1,N,E).

for_2(S,_,E) :- S > E,!,fail.
for_2(N,N,E).
for_2(S,N,E) :- S1 is S + 1,for_2(S1,N,E).