手短に
文献を十分に知らなかったので、次のセクションで説明する解決策と、最も難しい部分の証明を考え出しました。必要なものがわかったら、適切なアイデアを探すために文献を検索することができました。これは、文献に基づいたアルゴリズムの簡単な説明です。これは、基本的に私が開発したものと同じです。
最初にすることは、サイズが最小の終端文字列を見つけることです
σ(U) すべての非ターミナル U文法の。これは、コングラフまたはCFグラマーとしても知られるKnuthの拡張機能、およびダイクストラの最短経路アルゴリズムのグラフを使用して行うことができます。Knuthの論文の例Bは、ほとんど必要なことを実行します。
実際、Knuthはこれらの終端文字列の長さのみを計算しますが、このような終端文字列を実際に1つ計算するようにアルゴリズムを変更するのは非常に簡単です。 σ(U) 非端末ごとに U(以下の自分のバージョンで行うように)。また、σ(a)=a すべてのターミナル a、そして私たちは拡張します σ いつものように文字列準同型に。
次に、非終端がノードであり、アークがある有向グラフを考えます。 (U,V) ルールがある場合 U→αVβ。複数のそのようなルールが同じ弧を生成できる場合(U,V)、私たちは長さが |σ(αβ)|最小限です。弧はそのルールでラベル付けされ、その最小の長さは
|σ(αβ)| 弧の重みになります。
最後に、ダイクストラの最短経路アルゴリズムを使用して、最初の非終端からの最短経路を計算します S文法の各非終端に。非ターミナルの最短経路を考えるU、弧のルールラベルは、派生を取得するために使用できます。
S⟹∗αUβ。次に、フォームのすべてのルールにU→γ 文法では、サイズ最小の端末文字列を関連付けます σ(αγβ) これは、そのルールを使用して導出できます。
複雑さを軽減するために、ダイクストラのアルゴリズムとKnuthの拡張機能の両方が、ヒープ、別名優先キューで実装されています。これにより、ダイクストラのアルゴリズムは次のように複雑になります。O(nlogn+t)、およびKnuthのアルゴリズムの複雑さ O(mlogn+t)、 どこに〜がある m
文法規則と n 非端末、および tすべてのルールの全長です。全体は、Knuthのアルゴリズムの複雑さに支配されています。m≥n。
以下は、上記の短い答えを出す前の自分の作品です。
無駄なシンボル除去アルゴリズムからソリューションを導き出します。
このアルゴリズムにはいくつかの側面があります。より直感的にするために、私はそれを次第に多くの機能を導入する3つの連続したバージョンで提示することにしました。最初のバージョンは質問に答えませんが、解決策を提案する無用なシンボル除去のための標準アルゴリズムです。2番目のバージョンは、最小性の制約なしで質問に答えます。3番目のバージョンは、質問への回答を提供し、最小限の制約を満たします。この3番目のソリューションは、ダイクストラの最短経路アルゴリズムの and-orグラフへの適応を使用することで改善されます。
最終結果は非常に単純なアルゴリズムであり、すでに行われた計算の再検討を回避します。しかし、それは直感的ではなく、証明が必要です。
この回答は、OPのコメントで正確に説明されている質問にのみ答えようとします。「各プロダクションルールについて、パーサーを開始状態からテスト中のプロダクションを通じて一連の端末に渡す最小限の文字列を生成します。 "したがって、私は各ルールについて、ルールを使用して派生した言語のサイズ最小文字列の1つである文字列がセットにあるような文字列のセットを取得することのみを試みます。
ただし、文字列がルールを「呼び出す」、つまりそのルールを使用して派生したという事実は、曖昧な文法を処理し、あいまいさを任意に解決するパーサーによってルールが考慮されることを必ずしも意味しないことに注意する必要があります。そのような状況を処理するには、おそらくパーサーのより正確な知識が必要であり、より複雑な質問になる可能性があります。
基本的なアルゴリズム
この問題を解決するために、文脈自由文法での無用なシンボル除去のための古典的なアルゴリズムから始めることができます。これは、Hopcroft&Ullman、1979年版のセクション4.4、88-89ページにあります。ただし、ここでのプレゼンテーションは少し異なる場合があります。
このアルゴリズムは、OPから要求されたようなカバーの存在を証明することを目的としており、次の2つの部分で構成されています。
H&Uの補題4.1、88ページ:すべての非生産的な非終端記号の削除。これは、派生可能な端末文字列を端末ごとに検索しようとすることで行われます。それを説明する簡単な方法は次のとおりです:セットを作成しますProdすべてのターミナルで初期化するod生産的シンボル。次に、まだ処理されていない各ルールについて、右側(RHS)記号がすべて含まれていますProd、左側(LHS)の非終端記号をセットに追加します Prod、および処理するルールのセットから同じLHS非終端のすべてのルールを削除します。すべてのRHSシンボルを含むルールがなくなるまでプロセスを繰り返しますProd。にない残りの非ターミナルProd このプロセスの最後では、非生産的です。これらは終端文字列に派生できないため、文法から削除できます。
H&Uの補題4.2、89ページ:到達できないすべてのシンボルの削除。これは、非終端記号をノードと見なし、弧を持つことにより、有向グラフの従来のノード到達可能性によって行われます。(U,V) ルールがある場合 U→α そのような
V で発生します α。セットを作成しますReach 初期シンボルのみで初期化された到達可能なシンボルの数 S。次に、すべての非終端記号に対してU に Reach または後でそれに追加され、すべてのルールに対して U→αに追加します Reach のすべてのシンボル α。すべての非端末がReach このように処理された、に含まれていないすべてのシンボル(端末または非端末) Reach最初のシンボルから派生した文字列には出現できないため、役に立たない。したがって、それらは文法から削除できます。
これらの2つの基本的なアルゴリズムは、文脈自由言語と通常のセットの共通部分に使用されるような、いくつかの文法構築手法の生の結果を単純化するのに役立ちます。特に、これは一般的なCFパーサーの結果をクリーンアップするのに役立ちます。
それらを使用するルールが言語の文字列によって「呼び出される」(つまり、その派生で使用される)ことができないため、無用な非終端記号の削除が、質問の解決のコンテキストで必要です。
すべてのルールを呼び出す一連の文字列を作成する
(まだ最小限の文字列を探しているわけではありません。)
さて質問に具体的に答えると、到達不能なシンボルであろうと生産的でない非終端シンボルであろうと、LHSのような役に立たない非終端をもつ役に立たないルールと同様に、すべての役に立たないシンボルを確かに取り除く必要があります。ターミナル文字列の解析中にこれらが有効に呼び出される可能性はありません(ただし、削除されない場合、パーサーの処理時間を浪費する可能性があります。どのテクノロジーが時間を浪費するかは、パーサーテクノロジーによって異なります)。
次に、各(有用な)ルールについて、それを呼び出す、つまりこのルールを使用して生成される可能性のある端末ストリングの生成について検討します。これは基本的に上記の2つのアルゴリズムによって行われますが、非端末が到達可能で生産的であることを保証するためにこれらの文字列の存在を証明することに満足しているため、情報は保持されません。
最初のアルゴリズム(補題4.1)を、それぞれの非端末に合わせて変更します。 U セットで Prod 端末文字列 σ(U) それはに由来します: U⟹∗σ(U)。すべてのターミナルについて、σアイデンティティマッピングとして。いつU セットに追加されます Prod ルールのため
U→γ すべてのRHSシンボルが Prod、次に定義します
σ(U)=σ(γ)、拡張 σ 文字列の準同型として、すべて削除します U-rules、つまりすべてのルール U LHSとして。
2つ目のアルゴリズム(補題4.2)を、各非終端記号に合わせて変更します。 U に追加 Reach 最初のシンボルから到達するために使用されるパス S、派生を取得するための連続したルールを提供します S⟹∗αUβ。
次に、各ルールについて U→γ文法では、次のようにこのルールを「呼び出す」終端文字列を生成します。2番目のアルゴリズムの結果から導出
S⟹∗αUβ。次に、ルールを適用して文字列を取得しますαγβ。ルールを「呼び出す」終端文字列U→γ です σ(αγβ)
すべてのルールを「呼び出す」最小限の文字列のセットを構築する
これらの変更されたアルゴリズムの副産物である可能性のある不要なシンボルを排除する問題は無視します。
最小限の文字列のセットを構築するには、最初に各非端末の最小限の派生文字列を取得する必要があります。これは、最初のアルゴリズム(補題4.1)をさらに変更することによって行われます。まず、処理するルールのセットからすべての再帰ルールを削除します(つまり、RHS文字列にLHSシンボルが含まれています)。これらのルールのいずれも、同じLHSを持つ非再帰ルールよりも短い終端文字列を導出できないことは明らかです。また、LHSが無意味な非終端でない場合(非生産的であるため)、少なくとも1つの非再帰的ルールが必要です。
次に、以前と同様にセットを構築します Prod 各シンボルに関連付けられた生産的シンボルの U ターミナル文字列。 σ(U)。文字列σ(U) ルールの適用により以前と同様に生成されます U→γ、各非終端を置き換える V で発生 γ と σ(V)。これまでのところ、これは特定の非終端記号を持つ1つのルールのみに適用する必要がありました。U
そのLHSとして、最初にすべてのRHS非端末が
Prod、他の文字列は無視されるため、他の文字列は無視してください。しかし、今は最小限の派生文字列を探しています。したがって、非端末の場合U、これはすべてのルールで実行する必要があります ULHSとして。ただし、1つの終端文字列のみを保持しますσ(U)、新しいものが小さい場合は常に、現在のものを新しく見つかったもので置き換えます。
さらに、文字列はいつでも σ(U) より小さいルールに置き換えられます。 U変更により、より短い文字列でRHSを導出できるため、すでに処理されたRHSで、処理するルールのセットに戻す必要があります。したがって、これを行うと、より多くの反復が必要になりますが、これらの文字列は空の文字列よりもはるかに短くなることがないため、最終的には終了します。
この最初のアルゴリズムの最後に、文字列 σ(U) から導出できる最小の文字列の1つ U。他にもあるかもしれません。
ここで、すべての非ターミナルについて、取得する2番目のアルゴリズムも変更する必要があります。 U、(の1つ)唯一の非終端記号としてUを含む最短の文字列。これを行うには、ノードとして非ターミナルを使用し、アークを持つ同じ有向グラフを保持します(U,V) ルールがある場合
U→αVβ。ただし、アークに重みを付けて、到達可能な非ターミナルに関連付ける必要があるターミナルコンテキストの最小長を計算します。弧に関連付けられた重み(U,V) 上記は長さです |σ(αβ)|、マッピング σアイデンティティとしてターミナルに拡張され、文字列準同型として再び拡張されます。文字列から導出できる最短の終端文字列(の1つ)の長さです。
αβ。ご了承くださいVこの計算では削除されます。ただし、いくつかの発生がある場合VRHSでは、1つだけを削除する必要があります。いくつかの可能性があります(U,V) いくつかのルールがある場合、重みが異なる弧 U LHSおよび VRHSで。そのような場合、そのような明るいアーク(の1つ)だけが保持される。
このグラフでは、ノードの到達可能性だけを探すのではなく、
S、ただし最初のシンボルからすべてのノードに到達する最短の重み付きパスの場合 S。これは、ダイクストラのアルゴリズムで実行できます。
非ターミナルの最短経路を考える U、以前のように一連のルールとして読み取り、そこから派生を取得します
S⟹∗αUβ。次に、フォームのすべてのルールにU→γ 文法では、次のようにこのルールを「呼び出す」最小限の終端文字列を生成します
σ(αγβ)
備考:同じ最小限の文字列が複数のルールで使用される可能性があります。しかし、文字列の1つがルールを使用しているという事実ρ その派生では、必ずしもそのルールの最小文字列であることを意味するわけではありません ρ、別のルールで検出された可能性があるのに対し、より短いルールは ρ。柔軟性がある場合は常に、いくつかの優先順位ポリシーを使用することにより、同じ最小文字列が複数のルールで見つかる可能性を高めることができます。しかし、それは問題を起こす価値がありますか?
非端末から派生する最小限の端末文字列のためのより高速なアルゴリズム
関数の作成 σ そのような σ(U) から派生する最小限の終端文字列です U上記のかなり素朴な手法を使用して、いくつかの非終端に対して新しい小さな派生文字列が見つかったときに、すでに行われた作業を繰り返し再検討する必要があります。プロセスが明らかに終了する場合でも、これは無駄です。
ここでは、より効率的なアルゴリズム、つまり本質的に、And-orグラフのパスコンセプトを適切に定義して、ダイクストラの最短パスアルゴリズムをand-orグラフに拡張したCF文法グラフへの適応を提案します。 。アルゴリズムのこのバリアントはおそらく文献に存在します(それが正しいと仮定して)が、アクセスできるリソースでそれを見つけることができませんでした。したがって、私はそれを証明とともにより詳細に説明しています。
以前と同様に、最初に、処理するルールのセットからすべての再帰ルール(つまり、RHS文字列にLHSシンボルが含まれるルール)を削除します。これらの再帰ルールのいずれも、同じLHSを持つ非再帰ルールよりも短い終端文字列を導出できないことは明らかです。そして、LHSU 少なくとも1つの非再帰的である必要があります
Uシンボルの場合のルール U(非生産的であるため)役に立たない非ターミナルではありません。これは厳密には必要ありませんが、後で検討するルールの数を減らします。
次に、以前と同様にセットを構築します Prod 各シンボルに関連付けられた生産的シンボルの X ターミナル文字列。 σ(X)から導出可能なサイズ最小の端末文字列です
X (以前のアルゴリズムでは、それは終了後にのみ真実でした)。 Prod すべての終端記号で、各終端記号で初期化されます a、私たちは定義します σ(a)=a。
次に、すべてのルールを検討します U→γ すべてのRHSシンボルが Prod、そして私たちはそのようなものを選択します σ(γ)最小サイズです。次に追加しますU に Prod、 σ(U)=σ(γ)、すべて削除 U-ルール。すべての生産的ターミナルが入力されるまで繰り返しますProd。非ターミナルU、一度入力すると
Prod、変更するために再度考慮する必要はありません σ(U) 小さい文字列の場合。
証明:
以前のアルゴリズムは多かれ少なかれ直感的に明白でした。グラフのand-or特性のため、これは少しトリッキーであり、証明はより必要と思われます。実際に必要なのは、最後の反復に適用されたときにアルゴリズムの正確性を確立する次の補題だけです。
補題:アルゴリズムの各反復の後、σ(X) から導出可能なサイズ最小の端末文字列です X、 すべてのために X に Prod。
基本ステップは明白です。これは、定義により、すべてのターミナルに当てはまるためです。 Prod 初期化されたとき。
次に、いくつかの非端末が追加された後にそれが真であると仮定します
Prod、させて U→γ 新しい非ターミナルを追加するために選択されたルール Prod。このルールが選ばれたのは、
γ∈Prod∗ そして σ(γ) すべてのルールのすべてのRHSでサイズが最小であり、RHSが Prod∗。その後U に追加されます Prod、私たちはそれを証明する必要があります σ(γ) から導出可能なサイズ最小の端末文字列です U。
これは明らかに、ルールで始まるすべての派生の場合です
U→γ、帰納仮説により、マッピングの適用 σ のすべての非端末が σ are substituted with size-minimal terminal strings
deriving from them. Hence no other derivation can produce a shorter terminal string.
We thus consider only derivations starting with another U-rule
U→β, such that
β⟹∗w∈Σ∗,
where Σ is the set of terminal symbols.
If β∈Prod∗, then a minimal string it can derive on is
σ(β). But, since we chose the rule U→γ, it
must be that |σ(β)|≥|σ(γ)|. So the rule
U→β does not derive on a smaller terminal substring.
The last case to consider is when β∉Prod∗, and we then
consider a derivation β⟹∗w∈Σ∗.
If that derivation involves only non-trminals in Prod, then
β∈Prod∗, which is a case we have already seen. Hence we consider only
derivations that have steps using a rule with its LHS not in Prod.
Let V→α be such a rule, such that
α∈Prod∗.There must be at least one such rule since they
are partially ordered by derivation order, and w∈Prod∗.
Thus we have U⟹β⟹∗μVν. We know that μ and ν derive on a string of
size at least 0, and since no V-rule with a RHS in Prod∗ was chosen, they
derive on terminal strings of length at least equal to
|σ(γ)|. Hence, with the rule U→β, U
derives on a terminal string of length at least equal to
|σ(γ)|. ■