0

Ivan Bratkoの本「人工知能のプログラミング」を使用してPrologでDCG文法を勉強しています.PrologがDCG文法を一連のPrologルールに自動的に変換する方法を理解するための問題を見つけています。

たとえば、次の DCG 文法があります。

move --> step.
move --> step, move.

step --> [up].
step --> [down].

どこ:

mooveは可能な mooves のリストで、stepはまたはの 1 つの動きです。

したがって、移動のリストは単一の移動 (ステップ) である場合もあれば、単一の移動 (ステップ) の後に移動のリスト (移動) が続くと見なすことができる複数の移動で構成されたリストである場合もあります。

したがって、この文法は次のようなフレーズを生成できます: [up, down, down, up, down] または like: [up]

これはとても簡単です

次に、Prolog が以前の DCG 文法を一連の標準 Prolog ルールに自動的に変換する方法を示します (このコードを以前の DCG 文法と同じファイルに入れたため、名前を move2 および step2 に変更しました)。

/* move2 it is TRUE if the difference from the lists List and Rest is an
   acceptable move.
*/

/* BASE CASE: A moves list can be a single move (a step that can be "up" or "down")
   It is TRUE that the difference from the lists List and Rest is an acceptable move
   if it is TRUE that the head of the list is an acceptable move
*/
move2(List, Rest) :- step2(List, Rest).

/* GENERAL CASE: A moves list can be a single move followed by a list of moves.
   The difference of List1 and Rest is a valid move if it is TRUE that:
   the difference between List1 and List 2 is a step
   the difference between List2 and Rest is a move
*/ 
move2(List1, Rest) :- step2(List1, List2),
                      move2(List2, Rest).

/* step predicate extract a single step ("up" or "down") from a list
*/
step2([up|Rest], Rest).

step2([down|Rest], Rest).

コメントに書いたように、これらのルールの意味を解釈しようとしましたが、私の解釈についてはよくわかりません...

よく理解するためのヒントを教えてください。

TNX

アンドレア

4

1 に答える 1

0

コードや解釈に問題はないと思いますが、DCG として見なさずに「宣言的に」見ていると思います。代わりに、おそらくこのコードを次のように記述します。

step --> [up].
step --> [down].

move --> [].
move --> step, move.

これは同等に機能するはずですが、差分リストを明示的に維持しないため、拡張と維持はあなたのものよりもはるかに簡単です。

プロローグを意図の自然言語表現に近づけることができればできるほど、より良い結果が得られます。コードがどのように機能するかを説明するのに多くの言葉が必要な場合は、手続き型プログラミングを行っています。上記の Prolog は、すぐに使える限り近いものです。いくつかのヘルパーを作成することで、さらに進めることができます。

one_or_more(_, [])    --> [].
one_or_more(R, [V|Vs]) --> 
  { Rule =.. [R, V] }, 
  Rule, 
  one_or_more(R, Vs).

step(up)   --> [up].
step(down) --> [down].

moves(Steps) --> one_or_more(step, Steps).

(上記のコードはテストされていません。) ポイントは、宣言型プログラミングの能力を示すことです。のような述語を書くのは手間がかかるかもしれませんがone_or_more//2、それができれば、プログラムの残りの部分はより宣言的なスタイルに昇格します。それがどのようone_or_more//2に機能するかはすぐには明らかではないため(機能する場合でも) 、 の周りにいくつかのコメントが必要になる場合があります。上記の宣言的な読み方は、「move(Steps) は 1 つ以上のステップに一致する」です。これは、私の元のバージョンの宣言的な読み方と、あなたのバージョンの宣言的な読み方と同じです。違いは、それぞれのコードが明らかに宣言的な読み方に近いことです。

于 2013-05-15T17:17:35.857 に答える