文法規則 ( dcg ) には、(',')//2
連結を('|')//2
意味する、代替を意味するなど、いくつかの事前定義された構造があります(\+)//1
。
個人的に、私はそれを使用するためだけに使用しました。他の人が書いたコードでそれを見たことがありません。
それで、合法的な使用法はあり(\+)//1
ますか?
編集:さらに、インスタンス化されていない変数を使用し(\+)//1
たクエリ内での正当な使用法があります。phrase(nt, L)
L
文法規則 ( dcg ) には、(',')//2
連結を('|')//2
意味する、代替を意味するなど、いくつかの事前定義された構造があります(\+)//1
。
個人的に、私はそれを使用するためだけに使用しました。他の人が書いたコードでそれを見たことがありません。
それで、合法的な使用法はあり(\+)//1
ますか?
編集:さらに、インスタンス化されていない変数を使用し(\+)//1
たクエリ内での正当な使用法があります。phrase(nt, L)
L
\+ を使用して、あいまいさの少ない文法を作成できます。! よりも \+ を使用する利点 たとえば、\+ の特定の宣言性であるため、たとえば結果の DCG ルールを並べ替えることができます。
例を挙げてみましょう。次の文法を考えてみましょう。
s([X|Y]) --> t(X), s(Y). % 1
s([]) --> []. % 2
t(2) --> [a,a]. % 3
t(1) --> [a]. % 4
上記の文法は非常にあいまいです。たとえば、次の入力に対して複数の解析が行われます。
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
A = [2,1,2] ;
A = [2,1,1,1] ;
etc..
ここで、t の短い解析よりも t の長い解析を優先したいとします。次のようにカットでこれを行うことができます:
t(2) --> [a,a], !. % 5
t(1) --> [a]. % 6
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
残念ながら再注文はできません。以下を実行しても、望ましい結果が得られないためです。s(A) は異なる順序で結果を生成するようになりましたが、文法があいまいであるため、振り出しに戻ります。
t(1) --> [a]. % 7
t(2) --> [a,a], !. % 8
?- phrase(s(A),[a,a,a,a,a]).
A = [1,1,1,1,1] ;
A = [1,1,1,2] ;
A = [1,1,2,1] ;
etc...
\+ で同じことを試してみましょう。カットを次の否定に置き換えることができます。
t(2) --> [a,a]. % 9
t(1) --> [a], \+ [a]. % 10
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
並べ替えができるか試してみましょう。t//1 の文法規則を並べ替えます。
t(1) --> [a], \+ [a]. % 11
t(2) --> [a,a]. % 12
?- phrase(s(A),[a,a,a,a,a]).
A = [2,2,1] ;
No
宣言性は非常に便利です。たとえば、任意の順序で文法規則を選択する右から左へのチャート パーサーで \+ を使用できることを意味します。宣言性により、DCG ルールの入力順序に関係なく、チャート パーサーのボトムアップ フォワード チェーンが同じ結果をもたらすことが保証されます。
その後、DCG 手法を大規模な自然言語 (NL) プロジェクトに適用することが可能になり、スケーリングもうまくいきます。NL 文法は、経験的に決定論に合わせることができます。文法がより決定論的であるほど、その構文解析はより効率的になります。そうでなければ扱いにくい複雑な NL 文法が実現可能になります。
さよなら
L がインスタンス化されていない場合、文法がテキスト生成に使用されます。その場合、文法 \+ はまったく必要ありません。一部のテキストからのあいまいさの問題がなくなりました。
例を挙げてみましょう。次の文法を考えてみましょう。
s([X|Y]) --> t(X), s(Y). % 1
s([]) --> []. % 2
t(2) --> [a,a]. % 3
t(1) --> [a]. % 4
それぞれの異なる解析には、異なる解析ツリーがあります。また、phrase/2 を使用してテキストを生成することにあいまいさはありません。次のクエリは、正確に 1 つの答えを返します。
?- phrase(s([2,1]),L).
L = [a,a,a]
?- phrase(s([1,2]),L).
L = [a,a,a]
?- phrase(s([1,1,1]),L).
L = [a,a,a]
しかし、再利用の問題が少しあります。構文解析用の \+ を含む NL 文法があるとします。その後、解析に使用できません。\+ ゴールのインスタンス化パターンが異なるため、構成のセマンティックが変更されます。
解決策は、おそらく 2 つの文法を使用することです。1 つは解析用、もう 1 つは解析解除用です。解析と解析解除は、2 つの異なる認知機能だと思います。学校では、読む練習と書く練習があったことを思い出してください。同じことがコンピューターサイエンスでも起こります。
場合によっては、単一の文法を使用し、 \+ を曖昧さを解消するための注釈として表示することも可能だと思います。これは、解析中に削除されるか、別の方法で処理されます。そのようなメカニズムを構築することができます。しかし、解析と解析の問題はさらに深刻です。補助条件の双方向性({}/1)、解析解除中の左再帰など...
さよなら