1

私はPrologを初めて使用し、大学の試験のために勉強しています。SWIPrologを使用しています。

リストSがリストLのサブリストである場合にTRUEと表示されるこの単純なプログラムがどのように機能するかを理解するには、問題があります。それ以外の場合は、述語がFALSEと表示されます。

私は次の解決策を持っていますが、それが宣言的な意味を理解するのにいくつかの問題があります

この本を読んで、私はいくつかの考えを持っていたと思いますが、それについてはよくわかりません...

これは、連結を使用するソリューションです。

sublist(S,L) :- conc(L1, L2, L),
            conc(S, L3, L2).

conc([],L,L).

conc([X|L1],L2,[X|L3]) :- conc(L1,L2,L3).

このソリューションは、3番目のリストが最初のリストと2番目のリストの連結である場合にTRUEに応答する他の小さなプログラムを使用します。

LのSiサブリストがTRUEである必要がある場合、次の2つの条件があります。

  1. Lは、L1とL2を連結したリストである必要があります
  2. L2は、 S(Lリストに存在する場合は私のサブリスト)と別のリストL3を連結したリストである必要があります。

これは本の説明ですが、私にとってはほんの少しの難解です...

私はそれについて推論し、本当に深く意味することを理解しようとしました...

したがって、ある意味では、この他のプログラムを使用して、要素がリストのメンバーであるかどうかを検索するようなものだと思います。

member2(X, [X|_]).

member2(X,[_|T]):- member2(X,T).

このプログラムでは、Xがリストの一番上(その先頭)の要素である場合、Xはリストにあり、プログラムはtrueと応答します。それ以外の場合、X要素がリストの一番上にない場合(またはそれが私の解決策ではない場合)、このリストのTAILTで検索しようとします。

サブリストプログラムに戻る理由は似ていると思います

まず、Lリストを2つのリストL1とL2に分解します(concプログラムを使用)**

次に、SとL3の連結がL2リストであることが正しいかどうかを確認します。

ブースこれらの条件が真である場合、SはLのサブリストです

L1リストには、メンバープログラムのリストから抽出したX要素と同様の役割があると思います。

サブリストSはリストLの先頭から開始できるため、L1は[]になり、L1 = []とL2の連結でLを分解でき、SとL3でL2を分解できるようになります。

この最後の分解を行うことができれば、プログラムは終了し、Sが元のリストLのサブリストであることは事実であると言えます。

conc(S、L3、L2)が正しくない場合は、ddoをバックトラックして、他の計算ブランチを実行します。

私の宣言的解釈は正しいですか?

私はこの例で大きな困難を見つけています、私は手続き型の説明も見つけようとしました(Prologシェルの操作トレースを使用して)が、計算が非常に大きいため、短いリストでも大きな問題があります...

4

1 に答える 1

1

本の説明は、Prologの検索メカニズムを呼び出さないため、より宣言的です。私はおそらくこれをもっとアンダースコアで書くでしょう:

sublist(S, L) :- append(_, Suffix, L), append(S, _, Suffix).

これにより、少なくともSとL2(サフィックスに名前が変更されました)の関係がもう少し明確になります。私たちが言おうとしていること、そしてこれを宣言型英語で明確に表現するのは難しいですが、接尾辞と呼ばれるLの接尾辞があり、Sが接尾辞の接頭辞である場合、SはLのサブリストです。他の構成要素に名前を付けると、混乱が生じるだけです。Prologはこれらの変数に内部的に名前を付け、他のすべてを統合しようとするときに何かを統合しますが、その情報を呼び出し元と共有することはありません。これらの変数はある意味で存在する必要がありますが、数式に密接に関係していないか、シングルトンではありません。シングルトン変数の警告が表示されたら、変数をアンダースコアに置き換えてください。それは明快さを追加します。

関連するプレフィックスとサフィックスは空のリストである可能性があるため、SはLの適切なプレフィックスまたはLの適切なサフィックスである可能性があり、すべてがうまくいきます。

member/2参考までに、の宣言型の読みは、 Xがリストの先頭である場合、またはXがリストの末尾のメンバーである場合、Xはリストのメンバーです。何が欠けているかに注意してください。チェック、成功または失敗、あるいは実際には操作の順序についての言及です。Xがテールのメンバーである場合、またはヘッドである場合、Xがリストのメンバーであると言うことも同様に宣言的です。コンピュータに計算を実行させるには特定の順序で実行する必要があるのは避けられない事実です。したがって、Prologに正しい順序で指示する必要があります。そうしないと、無限ループに入りますが、これはロジック、Prologだけ。

他にも何度か説明したように、Prologの機構を呼び出すと、宣言型の読み取りではなくなります。たとえば、「最初に分解します...」と言うと、すでに宣言型の世界を離れ、手続き型の世界に入っています。Prologは実際のコンピューターで計算を実行するために特定の順序で処理を実行する必要がありますが、宣言型の世界にはステップがありません。同様に、宣言型のリーディングでは、物事をチェックしません。単にチェックするかしないかです。バックトラックという単語は、宣言型の読み取りの一部として表示することもできません。宣言型の読みで使用する必要がある唯一の「動詞」は、「である」という動詞です。

そうは言っても、あなたのプロローグ/手続きの読みは完全に正しいです。

于 2013-03-25T16:27:30.947 に答える