Como afirman las otras respuestas, las revisiones no agregan ningún poder adicional a las expresiones regulares.
Creo que podemos mostrar esto usando lo siguiente:
One Pebble 2-NFA (consulte la sección Introducción del documento que se refiere a él).
El 2NFA de 1 guijarro no se ocupa de los lookaheads anidados, pero podemos usar una variante de 2NFA de varios guijarros (ver la sección a continuación).
Introducción
Un 2-NFA es un autómata finito no determinista que tiene la capacidad de moverse hacia la izquierda o hacia la derecha en su entrada.
Una máquina de un guijarro es donde la máquina puede colocar un guijarro en la cinta de entrada (es decir, marcar un símbolo de entrada específico con un guijarro) y hacer posiblemente diferentes transiciones en función de si hay un guijarro en la posición de entrada actual o no.
Se sabe que el One Pebble 2-NFA tiene el mismo poder que un DFA normal.
Lookaheads no anidados
La idea básica es la siguiente:
El 2NFA nos permite retroceder (o 'pista delantera') moviéndonos hacia adelante o hacia atrás en la cinta de entrada. Entonces, para una búsqueda anticipada, podemos hacer la coincidencia de la expresión regular anticipada y luego retroceder lo que hemos consumido, al hacer coincidir la expresión anticipada. Para saber exactamente cuándo dejar de dar marcha atrás, ¡usamos el guijarro! Dejamos caer el guijarro antes de ingresar al dfa para que la mirada hacia adelante marque el lugar donde debe detenerse el retroceso.
Por lo tanto, al final de ejecutar nuestra cadena a través del guijarro 2NFA, sabemos si coincidimos con la expresión anticipada o no y la entrada que queda (es decir, lo que queda por consumir) es exactamente lo que se requiere para igualar el resto.
Entonces, para una búsqueda anticipada de la forma u (? = V) w
Tenemos los DFA para u, v y w.
Desde el estado de aceptación (sí, podemos asumir que solo hay uno) de DFA para u, hacemos una transición electrónica al estado inicial de v, marcando la entrada con un guijarro.
Desde un estado de aceptación para v, pasamos a un estado que sigue moviendo la entrada hacia la izquierda, hasta que encuentra un guijarro, y luego pasa al estado inicial de w.
Desde un estado de rechazo de v, hacemos una e-transición a un estado que sigue moviéndose hacia la izquierda hasta que encuentra el guijarro, y pasa al estado de aceptación de u (es decir, donde lo dejamos).
La prueba utilizada para NFA regulares para mostrar r1 | r2, o r *, etc., se transfieren a estos 2nfas de un guijarro. Ver http://www.coli.uni-saarland.de/projects/milca/courses/coal/html/node41.html#regularlanguages.sec.regexptofsa para obtener más información sobre cómo se ensamblan las máquinas componentes para obtener una máquina más grande para la expresión r *, etc.
La razón por la que funcionan las pruebas anteriores para r * etc es que el retroceso asegura que el puntero de entrada esté siempre en el lugar correcto, cuando ingresamos el componente nfas para la repetición. Además, si se está utilizando un guijarro, una de las máquinas de componentes anticipados lo está procesando. Dado que no hay transiciones de una máquina de mirar hacia adelante a una máquina de mirar hacia adelante sin retroceder completamente y recuperar el guijarro, todo lo que se necesita es una máquina de un guijarro.
Por ejemplo, considere ([^ a] | a (? = ... b)) *
y la cuerda abbb.
Tenemos abbb que pasa por peb2nfa para a (? = ... b), al final del cual estamos en el estado: (bbb, emparejado) (es decir, en la entrada bbb está restante, y ha coincidido con 'a' seguido de '..b'). Ahora, debido al *, volvemos al principio (ver la construcción en el enlace de arriba) e ingresamos el dfa para [^ a]. Haga coincidir b, vuelva al principio, ingrese [^ a] nuevamente dos veces y luego acepte.
Tratar con Lookaheads anidados
Para manejar lookaheads anidados, podemos usar una versión restringida de k-pebble 2NFA como se define aquí: Resultados de complejidad para autómatas bidireccionales y multi-pebble y sus lógicas (ver Definición 4.1 y Teorema 4.2).
En general, 2 autómatas guijarros pueden aceptar conjuntos no regulares, pero con las siguientes restricciones, se puede demostrar que los autómatas k-guijarros son regulares (Teorema 4.2 en el artículo anterior).
Si los guijarros son P_1, P_2, ..., P_K
P_ {i + 1} no se puede colocar a menos que P_i ya esté en la cinta y P_ {i} no se puede recoger a menos que P_ {i + 1} no esté en la cinta. Básicamente, los guijarros deben usarse de manera LIFO.
Entre el momento en que se coloca P_ {i + 1} y el momento en que se toma P_ {i} o se coloca P_ {i + 2}, el autómata puede atravesar solo la subpalabra ubicada entre la ubicación actual de P_ {i} y el final de la palabra de entrada que se encuentra en la dirección de P_ {i + 1}. Además, en esta subpalabra, el autómata sólo puede actuar como un autómata de 1 guijarro con Guijarro P_ {i + 1}. En particular, no está permitido levantar, colocar o incluso sentir la presencia de otro guijarro.
Entonces, si v es una expresión de anticipación anidada de profundidad k, entonces (? = V) es una expresión de anticipación anidada de profundidad k + 1. Cuando ingresamos a una máquina de mirar hacia adelante, sabemos exactamente cuántos guijarros se han colocado hasta ahora y, por lo tanto, podemos determinar exactamente qué guijarro colocar y cuando salimos de esa máquina, sabemos qué guijarro levantar. Todas las máquinas en la profundidad t se ingresan colocando el guijarro ty se sale (es decir, volvemos al procesamiento de una máquina de profundidad t-1) quitando el guijarro t. Cualquier ejecución de la máquina completa parece una llamada dfs recursiva de un árbol y las dos restricciones anteriores de la máquina multi-guijarros pueden ser atendidas.
Ahora, cuando combina expresiones, para rr1, ya que concat, los números de guijarros de r1 deben incrementarse por la profundidad de r. Para r * y r | r1, la numeración de los guijarros sigue siendo la misma.
Por lo tanto, cualquier expresión con lookaheads se puede convertir en una máquina de múltiples guijarros equivalente con las restricciones anteriores en la colocación de guijarros y, por lo tanto, es regular.
Conclusión
Básicamente, esto soluciona el inconveniente de la prueba original de Francis: poder evitar que las expresiones de anticipación consuman cualquier cosa que sea necesaria para futuras coincidencias.
Dado que los Lookbehind son solo cadenas finitas (no realmente expresiones regulares), podemos tratar con ellos primero y luego con los lookaheads.
Perdón por la redacción incompleta, pero una prueba completa implicaría dibujar muchas figuras.
Me parece correcto, pero me alegrará saber si hay algún error (que parece que me gusta :-)).