Wie die anderen Antworten behaupten, verleihen Lookarounds regulären Ausdrücken keine zusätzliche Kraft.
Ich denke, wir können dies folgendermaßen zeigen:
Ein Pebble 2-NFA (siehe den Abschnitt Einführung, der sich darauf bezieht).
Der 1-Pebble 2NFA behandelt keine verschachtelten Lookaheads, aber wir können eine Variante von Multi-Pebble 2NFAs verwenden (siehe Abschnitt unten).
Einführung
Ein 2-NFA ist ein nicht deterministischer endlicher Automat, der sich bei seiner Eingabe entweder nach links oder rechts bewegen kann.
Bei einer Ein-Kiesel-Maschine kann die Maschine einen Kiesel auf das Eingabeband legen (dh ein bestimmtes Eingabe-Symbol mit einem Kiesel markieren) und möglicherweise unterschiedliche Übergänge ausführen, je nachdem, ob sich an der aktuellen Eingabeposition ein Kiesel befindet oder nicht.
Es ist bekannt, dass der One Pebble 2-NFA die gleiche Leistung wie ein normaler DFA hat.
Nicht verschachtelte Lookaheads
Die Grundidee lautet wie folgt:
Mit dem 2NFA können wir zurückverfolgen (oder 'vordere Spur'), indem wir uns im Eingabeband vorwärts oder rückwärts bewegen. Für einen Lookahead können wir also das Match für den regulären Lookahead-Ausdruck durchführen und dann zurückverfolgen, was wir verbraucht haben, indem wir den Lookahead-Ausdruck abgleichen. Um genau zu wissen, wann das Backtracking beendet werden muss, verwenden wir den Kiesel! Wir lassen den Kiesel fallen, bevor wir die dfa für den Lookahead betreten, um die Stelle zu markieren, an der das Zurückverfolgen aufhören muss.
Am Ende des Durchlaufens unseres Strings durch den Kiesel 2NFA wissen wir also, ob wir mit dem Lookahead-Ausdruck übereinstimmen oder nicht, und die verbleibende Eingabe (dh was noch verbraucht werden muss) ist genau das, was erforderlich ist, um mit dem verbleibenden übereinzustimmen.
Also für einen Lookahead der Form u (? = V) w
Wir haben die DFAs für u, v und w.
Vom akzeptierenden Zustand (ja, wir können annehmen, dass es nur einen gibt) von DFA für u machen wir einen e-Übergang zum Startzustand von v und markieren die Eingabe mit einem Kieselstein.
Von einem akzeptierenden Zustand für v e-transtion in einen Zustand, der die Eingabe nach links bewegt, bis sie einen Kieselstein findet, und dann in den Startzustand von w übergeht.
Von einem ablehnenden Zustand von v gehen wir in einen Zustand über, der sich weiter nach links bewegt, bis er den Kiesel findet, und transtionen in den akzeptierenden Zustand von u (dh wo wir aufgehört haben).
Der Beweis, der für reguläre NFAs verwendet wird, um r1 | zu zeigen r2 oder r * etc übertragen für diese einen Kiesel 2nfas. Siehe http://www.coli.uni-saarland.de/projects/milca/courses/coal/html/node41.html#regularlanguages.sec.regexptofsa für weitere Informationen darüber , wie die Komponentenmaschinen zusammengesetzt werden , um die größere Maschine zu geben , für den r * Ausdruck etc.
Der Grund, warum die obigen Beweise für r * usw. funktionieren, ist, dass das Backtracking sicherstellt, dass sich der Eingabezeiger immer an der richtigen Stelle befindet, wenn wir die Komponente nfas zur Wiederholung eingeben. Wenn ein Kieselstein verwendet wird, wird er von einer der Lookahead-Komponentenmaschinen verarbeitet. Da es keine Übergänge von Lookahead-Maschine zu Lookahead-Maschine gibt, ohne den Kiesel vollständig zurückzuverfolgen und zurückzugewinnen, ist nur eine Ein-Kiesel-Maschine erforderlich.
Betrachten Sie beispielsweise ([^ a] | a (? = ... b)) *
und die Zeichenfolge abbb.
Wir haben abbb, das die peb2nfa für a (? = ... b) durchläuft, an dessen Ende wir uns im Zustand befinden: (bbb, Matched) (dh in der Eingabe bleibt bbb übrig, und es hat 'a' abgeglichen gefolgt von '..b'). Aufgrund des * kehren wir nun zum Anfang zurück (siehe die Konstruktion im obigen Link) und geben die dfa für [^ a] ein. Match b, gehe zurück zum Anfang, gib zweimal zweimal [^ a] ein und akzeptiere dann.
Umgang mit verschachtelten Lookaheads
Um verschachtelte Lookaheads zu verarbeiten, können wir eine eingeschränkte Version von k-pebble 2NFA verwenden, wie hier definiert: Komplexitätsergebnisse für Zweiwege- und Multi-Pebble-Automaten und ihre Logik (siehe Definition 4.1 und Satz 4.2).
Im Allgemeinen können 2 Kieselautomaten nicht reguläre Mengen akzeptieren, aber mit den folgenden Einschränkungen kann gezeigt werden, dass k-Kieselautomaten regulär sind (Satz 4.2 im obigen Artikel).
Wenn die Kieselsteine P_1, P_2, ..., P_K sind
P_ {i + 1} darf nicht platziert werden, es sei denn, P_i befindet sich bereits auf dem Band, und P_ {i} darf nicht aufgenommen werden, es sei denn, P_ {i + 1} befindet sich nicht auf dem Band. Grundsätzlich müssen die Kieselsteine LIFO-artig verwendet werden.
Zwischen dem Zeitpunkt, an dem P_ {i + 1} platziert wird, und dem Zeitpunkt, an dem entweder P_ {i} aufgenommen oder P_ {i + 2} platziert wird, kann der Automat nur das Unterwort durchlaufen, das sich zwischen dem aktuellen Standort von P_ {i} befindet und das Ende des Eingabeworts, das in der Richtung von P_ {i + 1} liegt. Darüber hinaus kann der Automat in diesem Unterwort nur als 1-Kiesel-Automat mit Pebble P_ {i + 1} fungieren. Insbesondere ist es nicht gestattet, das Vorhandensein eines anderen Kiesels anzuheben, zu platzieren oder gar zu spüren.
Wenn also v ein verschachtelter Lookahead-Ausdruck der Tiefe k ist, dann ist (? = V) ein verschachtelter Lookahead-Ausdruck der Tiefe k + 1. Wenn wir eine Lookahead-Maschine betreten, wissen wir genau, wie viele Kieselsteine bisher platziert worden sein müssen, und können so genau bestimmen, welche Kieselsteine platziert werden sollen, und wenn wir diese Maschine verlassen, wissen wir, welche Kieselsteine angehoben werden müssen. Alle Maschinen in der Tiefe t werden durch Platzieren des Kiesels t eingegeben und durch Entfernen des Kiesels t verlassen (dh wir kehren zur Verarbeitung einer Maschine der Tiefe t-1 zurück). Jeder Lauf der gesamten Maschine sieht aus wie ein rekursiver dfs-Aufruf eines Baums, und die beiden oben genannten Einschränkungen der Multi-Pebble-Maschine können berücksichtigt werden.
Wenn Sie nun Ausdrücke für rr1 kombinieren, müssen die Kieselzahlen von r1 um die Tiefe von r erhöht werden, da Sie sich darauf konzentrieren. Für r * und r | r1 bleibt die Kieselnummerierung gleich.
Somit kann jeder Ausdruck mit Lookaheads in eine äquivalente Multi-Pebble-Maschine mit den oben genannten Einschränkungen bei der Platzierung von Kieselsteinen konvertiert werden und ist daher regelmäßig.
Fazit
Dies behebt im Wesentlichen den Nachteil von Francis 'ursprünglichem Beweis: Es kann verhindert werden, dass die Lookahead-Ausdrücke alles verbrauchen, was für zukünftige Spiele erforderlich ist.
Da Lookbehinds nur endliche Zeichenfolgen sind (nicht wirklich Regexs), können wir uns zuerst mit ihnen und dann mit den Lookaheads befassen.
Entschuldigen Sie die unvollständige Beschreibung, aber ein vollständiger Beweis würde das Zeichnen vieler Zahlen beinhalten.
Es sieht für mich richtig aus, aber ich werde mich über Fehler freuen (die ich anscheinend gern habe :-)).