他の回答が主張するように、ルックアラウンドは正規表現に特別な力を追加しません。
これは、次のように示すことができると思います。
1 つの小石 2-NFA (それを参照する論文の概要セクションを参照してください)。
1-pebble 2NFA はネストされた先読みを処理しませんが、複数の Pebble 2NFA の変形を使用できます (以下のセクションを参照)。
序章
2-NFA は非決定論的な有限オートマトンであり、入力に対して左または右に移動することができます。
ワン ペブル マシンは、マシンが入力テープにペブルを配置し (つまり、特定の入力記号をペブルでマークする)、現在の入力位置にペブルがあるかどうかに基づいて異なる遷移を行うことができる場所です。
One Pebble 2-NFA は、通常の DFA と同じパワーを持つことが知られています。
ネストされていない先読み
基本的な考え方は次のとおりです。
2NFA を使用すると、入力テープを前後に移動してバックトラック (または「フロント トラック」) することができます。したがって、先読みのために、先読み正規表現の照合を行い、先読み表現の照合で、消費したものをバックトラックできます。バックトラックを停止するタイミングを正確に知るために、小石を使用します。バックトラッキングを停止する必要がある場所をマークするために、先読みのために dfa に入る前に小石を落とします。
したがって、小石の 2NFA を介して文字列を実行する最後に、先読み式と一致したかどうかがわかり、残りの入力 (つまり、消費されるために残っているもの) は、残りのものと一致するために必要なものです。
したがって、形式 u(?=v)w の先読みについては
u、v、w の DFA があります。
u の DFA の受け入れ状態 (はい、1 つしかないと仮定できます) から、v の開始状態に e-transition を作成し、入力を小石でマークします。
v の受け入れ状態から、小石が見つかるまで入力を左に移動し続ける状態に e-transtion し、その後 w の開始状態に遷移します。
v の拒否状態から、小石を見つけるまで左に移動し続ける状態に e-遷移し、u の受け入れ状態 (つまり、中断した場所) に遷移します。
通常の NFA で r1 | を示すために使用される証明。r2、または r* などは、これら 1 つの小石 2nfas に対して繰り越されます。コンポーネント マシンを組み合わせてより大きなマシンにする方法の詳細については、http://www.coli.uni-saarland.de/projects/milca/courses/coal/html/node41.html#regularlanguages.sec.regexptofsaを参照してください。 r* 式など
上記の r* などの証明が機能する理由は、繰り返しのためにコンポーネント nfas を入力したときに、バックトラッキングによって入力ポインターが常に正しい場所にあることが保証されるためです。また、pebble が使用されている場合は、先読みコンポーネント マシンの 1 つによって処理されています。先読みマシンから先読みマシンへの移行は、完全にバックトラックして小石を取り戻さなければならないため、1 台の小石マシンで十分です。
たとえば、 ([^a] | a(?=...b))* を考えてみましょう
および文字列abbb。
a(?=...b) の peb2nfa を通過する abbb があり、その最後に次の状態になります: (bbb、一致) (つまり、入力 bbb が残っており、「a」と一致しています) '..b' が続きます)。* があるので、最初に戻り (上のリンクの構造を参照)、[^a] の dfa を入力します。b に一致し、最初に戻り、[^a] を 2 回入力して受け入れます。
ネストされた先読みの処理
入れ子になった先読みを処理するために、ここで定義されているように k-pebble 2NFA の制限付きバージョンを使用できます:双方向オートマトンとマルチペブル オートマトンの複雑さの結果とそのロジック(定義 4.1 と定理 4.2 を参照)。
一般に、2 pebble オートマトンは非正則集合を受け入れることができますが、次の制限により、k-pebble オートマトンは正則であることを示すことができます (上の論文の定理 4.2)。
小石が P_1、P_2、...、P_K の場合
P_i が既にテープ上にない限り、P_{i+1} を配置することはできず、P_{i+1} がテープ上にない場合を除き、P_{i} をピックアップすることはできません。基本的に小石は LIFO 方式で使用する必要があります。
P_{i+1} が配置されてから、P_{i} がピックアップされるか P_{i+2} が配置されるまでの間に、オートマトンは P_{i} の現在の位置の間にあるサブワードのみをトラバースできます。 P_{i+1} の方向にある入力単語の末尾。さらに、このサブワードでは、オートマトンは Pebble P_{i+1} を持つ 1-pebble オートマトンとしてのみ機能します。特に、別の小石を持ち上げたり、配置したり、その存在を感知したりすることは許可されていません。
したがって、v が深さ k のネストされた先読み式である場合、(?=v) は深さ k+1 のネストされた先読み式です。先読みマシンに入ると、これまでに置かれた小石の数が正確にわかっているため、どの小石を配置するかを正確に決定でき、そのマシンを出るときに、どの小石を持ち上げるかがわかります。深さ t のすべての機械は、小石 t を置くことによって入り、小石 t を取り除くことによって出ます (つまり、深さ t-1 の機械の処理に戻ります)。完全なマシンの実行は、ツリーの再帰的な dfs 呼び出しのように見え、マルチ ペブル マシンの上記の 2 つの制限に対応できます。
式を組み合わせると、rr1 について、連結するため、r1 の小石の数は r の深さだけインクリメントする必要があります。r* と r|r1 の小石の番号付けは同じままです。
したがって、先読みを使用した任意の式は、小石の配置に上記の制限がある同等の複数小石マシンに変換できるため、規則的です。
結論
これは基本的に、フランシスの元の証明の欠点に対処します: 先読み式が将来の一致に必要なものを消費するのを防ぐことができます。
後読みは単なる有限文字列 (実際には正規表現ではない) であるため、最初にそれらを処理し、次に先読みを処理できます。
不完全な記述で申し訳ありませんが、完全な証明には多くの図を描く必要があります.
私には正しいように見えますが、間違いがあれば喜んでお知らせします(私はそれが好きなようです:-))。