4

(X, Xs)Prologがより多くの要素を含むタプルと一致するのはなぜですか? 例:

test2((X, Xs)) :- write(X), nl, test2(Xs).                                    
test2((X)) :- write(X), nl.                                                   
                                                                              
test :-                                                                       
        read(W),                                                               
        test2(W). 

?- test.
|: a, b(c), d(e(f)), g.
a
b(c)
d(e(f))
g
yes

実際、これは私が達成したいことですが、疑わしいようです。Prolog で用語の接続詞をリストとして扱う他の方法はありますか?

4

2 に答える 2

4

演算子を使用したタプルの構築は、,/2通常、PROLOG では右結合 (通常はsequenceと呼ばれます) であるため、 の入力はa, b(c), d(e(f)), g実際には項である可能性があります(a, (b(c), (d(e(f)), g)))。これは、述語test2/1 が質問に示されている内容を出力したという事実によって証明されます。最初の呼び出しでは、 の最初の句test2/1XMatched 、次に 2 回目の呼び出しでは、MatchedとaMatchedXsなどです。(b(c), (d(e(f)), g))Xb(c)Xs(d(e(f)), g)

接続詞として解釈される用語のリストを本当に処理したい場合は、次のように使用できます。

test2([X|Xs]) :- write(X), nl, test2(Xs).                                    
test2([]).

...入力時[a, b(c), d(e(f)), g]。ここでのリスト構造は一般に、で構築されたタプルとは少し異なって解釈されます,/2(少なくとも SWI-PROLOG では、このような構造は、で構築された項を扱うための構文糖衣であり./2、シーケンスまたはタプル項を で構築するのとほぼ同じ方法です)。,/2)。このようにして、リスト用語をコード内で接続詞として解釈できる場合は、リスト用語のサポートの利点を得ることができます。もう 1 つの方法は、次のように宣言して、結合に独自の(おそらく中置演算子) を使用&/2することです。

:- op(500, yfx, &). % conjunction constructor

次に、接続詞を as として構築a & b(c) & d(e(f)) & gし、そこから適切に処理して、&/2接続詞の意味を正確に理解することができます。

詳細については、SWI-PROLOG のマニュアル ページを参照してくださいop/3。SWI を使用していない場合は、使用している PROLOG 実装に同様の述語があるはずです。価値がある場合は、salt :-)

編集:を使用して構築されたタプル項を,/2リストに変換するには、次のようなものを使用できます。

conjunct_to_list((A,B), L) :-
  !,
  conjunct_to_list(A, L0),
  conjunct_to_list(B, L1),
  append(L0, L1, L).
conjunct_to_list(A, [A]).
于 2010-05-24T00:28:40.773 に答える
0

うーん...a, b(c), d(e(f)), gaand(b(c)and(d(e(f))and g))を意味し、リスト[1,2,3]も単なる[1 | [2 | [3 | []]]]。です。つまり、その接続詞をリストに変換すると同じ結果が得られますがtest2([X|Xs]):-...、違いは、接続詞がその2つの目標がどのように組み合わされているかに関する情報を伝達することです(論理和もある可能性があり(X; Xs)ます)。そして、あなたは接続詞の他の階層を構築することができます(a, b(c)), (d(e(f)), g)

単純な再帰型を使用します。他の言語では、リストも再帰型ですが、多くの場合、配列(優れたインデックスを持つ大きな大きなタプル)のふりをしています。

おそらくあなたは使うべきです:

test2((X, Y)):- test2(X), nl, test2(Y).
test2((X; Y)). % TODO: handle disjunction
test2(X) :- write(X), nl.
于 2010-05-23T22:55:43.387 に答える