17

次のように機能する述語を探しています。

?- subset([1,2,3], X).
X = [] ;
X = [1] ;
X = [2] ;
X = [3] ;
X = [1, 2] ;
X = [1, 2, 3] ;
X = [2, 3] ;
...

いくつかの実装を見てきましsubsetたが、サブセットを生成したいときではなく、あるリストが別のリストのサブセットであるかどうかを確認したいときにすべて機能します。何か案は?

4

5 に答える 5

27

ここに実装があります:

subset([], []).
subset([E|Tail], [E|NTail]):-
  subset(Tail, NTail).
subset([_|Tail], NTail):-
  subset(Tail, NTail).

例に示されている順序ではありませんが、すべてのサブセットが生成されます。

コメント投稿者のリクエストに従って、ここに説明があります:

最初の句は基本ケースです。空のリストは空のリストのサブセットであると記載されています。

2番目と3番目の節は再帰を扱います。2番目の句は、2つのリストのヘッドが同じで、右側のリストの末尾が左側のリストの末尾のサブセットである場合、右側のリストは左側のリストのサブセットであると述べています。

3番目の句は、左側のリストの先頭をスキップし、右側のリストが左側のリストの末尾のサブセットである場合、右側のリストは左側のリストのサブセットであると述べています。

上記の手順では、順序集合が生成されます。順序付けされていないセットの場合は、次を使用できますpermutation/3

unordered_subset(Set, SubSet):-
  length(Set, LSet),
  between(0,LSet, LSubSet),
  length(NSubSet, LSubSet),
  permutation(SubSet, NSubSet),
  subset(Set, NSubSet).
于 2011-02-06T23:47:32.440 に答える
7

http://www.probp.com/publib/listut.htmlで、必要なことを実行するという述語の実装を見つけることができますsubseq0

subseq0(List, List).
subseq0(List, Rest) :-
   subseq1(List, Rest).

subseq1([_|Tail], Rest) :-
   subseq0(Tail, Rest).
subseq1([Head|Tail], [Head|Rest]) :-
   subseq1(Tail, Rest).

簡単な説明: subseq0(X, Y)Y が X の部分集合部分subseq1(X, Y)列であるかどうかを確認し、Y が X の適切な 部分部分列であるかどうかを確認します。

セットのデフォルトの表現は一意の要素を持つリストであるため、次の例のように、それを使用してすべてのサブセットを取得できます。

?- subseq0([1,2,3], X).
X = [1, 2, 3] ;
X = [2, 3] ;
X = [3] ;
X = [] ;
X = [2] ;
X = [1, 3] ;
X = [1] ;
X = [1, 2] ;
false.
于 2011-02-06T11:39:05.213 に答える
1

セットは、定義上、個別のオブジェクトのコレクションです。サブセット プロシージャは、セット内 (引数内) の要素の順序を気にする必要はありません。適切な解決策 (swi prolog) は次のようになります。

subset(_, []).
subset([X|L], [A|NTail]):-
    member(A,[X|L]),    
    subset(L, NTail),
    not(member(A, NTail)).

質問 ?-subset([1,2,3], E) の場合、以下が生成されます。

E = [] ;
E = [1] ;
E = [1, 2] ;
E = [1, 2, 3] ;
E = [1, 3] ;
E = [2] ;
E = [2, 3] ;
E = [3] ;
E = [3, 2] ;
false.

それが役立つことを願っています!

于 2016-01-01T14:06:57.907 に答える
1

スーパー セットからサブセットのアイテムを削除してテストすることもできます。

% to delete : an item can be deleted it its in the head or in the tail of a list
delete(I,[I|L],L).
delete(I,[H|L],[H|NL]) :- delete(I,L,NL).
% an [] is an item of an set.A set is a subset of we can recursively delete its head item from the super set.
subset(_,[]).
subset(S,[I|SS]) :- delete(I,S,S1), subset(S1,SS).

例:

subset([a,b,c],S).
S = []
S = [a]
S = [a, b]
S = [a, b, c]
S = [a, c]
S = [a, c, b]
S = [b]
S = [b, a]
S = [b, a, c]
S = [b, c]
S = [b, c, a]
S = [c]
S = [c, a]
S = [c, a, b]
S = [c, b]
S = [c, b, a] 

subset([a,b,a,d,e],[a,e]).
1true
于 2018-10-11T00:34:54.573 に答える
-2
append([],L,L).

append([H|T],L,[H|L1]):-append(T,L,L1).


subset([X|T],[X|L]) :-subset(T,L).

subset([X|T],[G|L]) :-subset([X],L),append(L2,[X|L3],[G|L]),append(L2,L3,L4),subset(T,L4).

subset([],_).

----------------------------------------------
?- subset([1,2],[1,2]).

yes

?- subset([1,2],[2,1]).

yes

?- subset([1,1],[1,2]).

no

?- subset(D,[1,2]).

D = [1,2] ;

D = [1] ;

D = [2,1] ;

D = [2] ;

D = '[]' ;

no
于 2014-04-29T07:31:21.813 に答える