2016-05-03 5 views
3

基本的に私の仕事は、2つのパラメータを含む述語で与えられたリストからSetを作成することです。Prologのリストからセットを作成する

最初のものがリストで、2番目がセットの値です。コード

2 ?- list2set([2,3,4,4] , X). 
X = [2, 3, 4|_G2840] . 

thatsの:

list2set([] , _). 
list2set([ListH|ListT] , Set) :- member(ListH, Set) , list2set(ListT , Set). 

本当に基本的なことのようですが

しかしどういうわけか、それは私の頭のように設定し、変数とテールが含まれているリストを与えます私が作った間違い。

+0

あなたの定義にセットとなるものは何ですか?ユニークな要素を持つリストをほしいだけですか?伝統的な定義によって「セット」されるということは、要素の順序付けは重要ではなく、それらはすべてユニークであることを意味する。エレメントの順序付けは、セットに対してどのような操作を実行するかを検討する場合にのみ意味を持ちます。 – lurker

+0

Setは代数データ型で、オブジェクトに与えられた関数がセットされているかどうかをO(1)で調べる関数を備えています。本質的に、キーが使用されていないハッシュマップです。リストには最悪の場合の検索時間がO(n)あり、通常、キャッシュミスを保証する不連続な割り当てによってリンクされます。セットがセットであるためには、O(1)アクセスタイムを償却しなければならない(MUST)。 – Dmitry

答えて

1

ユニークなリストを作成し、オープンな状態に保ちます。

あなたはコールlength(Set, _)、またはハンドコーディング同等(あまりにも、それは確定的にする)、作業が完了していると、それを閉じることができます:memberchk/2の代わりmember/2を呼び出すことを検討し、また

list2set([], S):- 
    % length(S, _), ! 
    close_it(S).   % use var/1 

また

list2set(X, X). 

を定義し、あなたがセットのために、あなたの表現で重複を許すと言って、「スマート」な答えを与えることができます。

2

まず、Prologにはセットがありません。リストはです。ですから、重複した要素を持つリストをリストに関連付けることはできません。 list_nub/2はこのような定義になります。あなたの現在の定義に

すでにlist2set([], [a])が正しいことができない、成功します。あなたの定義はあまりにも一般的です。 list2set([],_)list2set([],[])に置き換える必要があります。

次に、member(ListH, Set)member(ListH,ListT)に置き換えてください。

そして、あなたは要素が存在しない場合のために別のルールが必要になります。

list2set([] , []). 
list2set([E|Es] , Set) :- 
    member(E, Es) , 
    list2set(Es , Set). 
list2set([E|Es] , [E|Set]) :- 
    maplist(dif(E), Es), 
    list2set(Es , Set). 

冗長答えを回避し、よりコンパクトな定義はlist_nub/2です。


1)厳密に言えば、一つはがACI -unificationは本物のセットを持つように実装するのに起因する変数を経由して統一を拡張することができます。

2)私には、—とおおよそ—ということを理解するためには、SICStusで帰属変数を実装する必要があります。 SWIやYAPの現在のような他のインターフェースは、おそらく不十分です。 CLP(B)のためのものです。詳細については、this discussionを参照してください。

関連する問題