2012-05-01 4 views
0

リストが与えられたら、リスト内の可能な組み合わせの組み合わせをすべて計算したいと思います。Prologで与えられたリストのすべてのペアを述語化するには?

例えば2)入力リストである(A、B、C)Iペアを取得したい(B)(C)(B、C)

例えば、1)入力リストであります(a、b)(a、d)(b、c)(b、d)と(c、d)のペアを取得したいと考えています。

+0

'pairs(x:xs)= [(x、y)| y <-xs] ++対xs;ペア[] = [] '、ハスケル表記。最も簡単なのは、これをProlog述語に変換することです。これは、Mogの答えが示唆するように、バックトラック時にこれらのペアを1つ1つずつ生成します。 'y <-xs'は' member(Y、XS) 'に対応します。 '++'は論理和に対応します。 –

答えて

2

select/3を2回(または select/3回、 member/2回)使用すると、ここで必要なものを達成できます。私はあなたが細部を解決し、それがまだ面倒であれば助けを求めるようにします。

ところで、リストのためのPrologの構文は(a, b, c)しかし[a, b, c]ない(まあ、それはシンタックスシュガーですが、私はそれでそれを残しておきます)。

編集:@WillNessが指摘したように、あなたが任意のペア(X, Y)を探しているだけXは、リスト内のY前にあるペアのためにしていません。

DCGsは本当に良いフィット感です:似た中であなたはSWI-Prologのを使用し、append/2への呼び出しは、あまりにもトリックを行う場合は、代わりに

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

pair(L, X-Y) :- 
    phrase((..., [X], ..., [Y], ...), L). 

:@Falseが説明するように、彼らはgraphically appealing solutionを生成することができますやり方が、DCGsよりも効率が低い:

pair2(L, X-Y) :- 
    append([_, [X], _, [Y], _], L). 

@WillNessが彼のコメントで示唆されているようにあなたは、基本的な再帰でそれを行うことができます。必要に応じてこの部分を詳細に残しておきます!

+1

おそらくselect/3ではなく、入力リストに対する単純な再帰が必要です。なぜなら、最初に選択された要素の前に要素が必要ないからです(説明から、 '(b、a)'、 'c 、b) 'ペアなど)。 –

+0

ええ、私は十分に慎重に期待された出力をチェックしていない、あなたはanwerとしてあなたのコメントを投稿する必要があります! – m09

+0

が完了しました。宿題ではないことを願っています。 :) –

2

OK、そのバックトラックPrologの述語としてHaskellの

pairs (x:xs) = [ (x,y) | y<-xs ] 
       ++ pairs xs 
pairs []  = [] 

を変換するために、それはすべての可能なペアを取得するには

pair([X|XS],X-Y):- member(... ,XS). %% fill in the '...' here 
pair([_|XS],P) :- pair(XS, ...).  %% 
%% pair([],_) :- false. 

、簡単で短いですが、findall使用:

pairs(L,PS):- findall(P, pair(L,P), PS). 

あなたのリストがbagofの場合は、 sに論理変数を含めることができます。コントロールをbagofのバックトラックは複雑な問題かもしれません。

pairsもアキュムレータのパラメータによって、その出力リストを構築し、決定論的、非バックトラック、再帰的な定義のように書くことができます - ここでは実際にそれ差分リストになり、トップダウン方式、中:

pairs([X|T],PS):- T=[_|_], pairs(X,T,T,PS,[]) ; T=[], PS=[]. 
pairs([],[]). 

pairs(_,[],[],Z,Z). 
pairs(_,[],[X|T],PS,Z):- pairs(X,T,T,PS,Z). 
pairs(X,[Y|T],R,[X-Y|PS],Z):- pairs(X,T,R,PS,Z). 
+0

+1:いくつかのコメント:ハスケルには基本的な違いがあります。それが変数です。このため、 'findall/3'は変数を含むリストでは機能しません。 'bagof/3'を考えてみましょう。あなたの最後のバージョンでは、赤いカットを ''( - >)/ 2'のようにする必要はありません。あなたは 'T = [_ | _]' ... ';で完全に純粋にできます。 T = [] '。 '(:)/ 2'の代わりに、Prologの慣用組のコンストラクタである'( - )/ 2'を使います。 – false

+0

@偽のおかげで、それを変更しました。ここは緑色のカットですが、私は思っていました。ファンクタ名については、私はペアのために ':'を使いました。私にとっては ' - 'は、違いリストの慣用的な指標です。 :) –

+0

@false no、まったく緑色のカットではありません。 *赤*カットされました。 –

関連する問題