2013-03-11 10 views
14

Data un'espressione regolare R che descrive un linguaggio normale (nessuna retrocessione di fantasia). Esiste un modo algoritmico per costruire un'espressione regolare R * che descrive la lingua di tutte le parole ad eccezione di quelle descritte da R? Dovrebbe essere possibile in quanto Wikipedia dice:Esiste un modo per annullare un'espressione regolare?

I linguaggi regolari sono chiusi sotto le varie operazioni, vale a dire, se le lingue K e L sono regolari, così è il risultato delle seguenti operazioni: [ ...] il complemento ¬L

Ad esempio, dato l'alfabeto {a, b, c}, l'inverso della lingua (abc *) + è (un | (ac | b | c). *)?


Come DPenner ha già sottolineato nei commenti, l'inverso di un expresion regolare può essere esponenzialmente più grande della espressione originale. Ciò rende l'inversione delle espressioni regolari inadatta per implementare la sintassi di espressioni parziali negative per scopi di ricerca. Esiste un algoritmo che conserva la O (n * m) runtime caratteristica (dove n è la dimensione della regex e m è la lunghezza dell'input) dell'espressione regolare corrispondente e consente una sottoespressioni negati?

+7

Costruire l'NFA da regex, costruire il DFA da NFA (dovrebbe esserci un algo per questo), trasformare gli stati non-terminali in stati terminali e viceversa, quindi derivare la regex da DFA. – nhahtdh

+0

@nhahtdh Sembra un'idea interessante; il problema è che un NFA di lunghezza O (n) può corrispondere a un DFA di lunghezza O (2^n). – fuz

+0

Non ho analizzato correttamente questo argomento, ma non riesco a vedere come un NFA genererebbe un DFA più grande. Puoi mostrarmi un caso del genere? – nhahtdh

risposta

3

Sfortunatamente, la risposta fornita da nhahdtdh nei commenti è buona quanto possiamo fare (finora). Se una determinata espressione regolare genera tutte le stringhe è completa con PSPACE. Poiché tutti i problemi in NP sono completati con PSPACE, una soluzione efficiente al problema dell'universalità implicherebbe che P = NP.

Se ci fosse una soluzione efficiente al tuo problema, saresti in grado di risolvere il problema dell'universalità? Certo che lo faresti.

  1. Utilizzare l'algoritmo efficiente per generare un'espressione regolare per la negazione;
  2. Determina se l'espressione regolare risultante genera il set vuoto.

noti che il problema "data un'espressione regolare, non genera l'insieme vuoto" è piuttosto semplice:

  1. L'espressione regolare {} genera l'insieme vuoto.
  2. (r + s) genera il set vuoto se entrambi i valori r e s generano il set vuoto.
  3. (rs) genera il set vuoto se r o s genera il set vuoto.
  4. Nessun altro genera il set vuoto.

Fondamentalmente, è abbastanza facile capire se un'espressione regolare genera il set vuoto: basta iniziare a valutare l'espressione regolare.

(Si noti che mentre la procedura sopra è efficiente in termini di lunghezza di uscita, potrebbe non essere efficiente in termini di lunghezza di input, se la lunghezza di uscita è più che polinomiale più veloce della lunghezza di input. se così fosse, avremmo comunque lo stesso risultato, cioè che il tuo algoritmo non è veramente efficiente, dal momento che richiederebbero in modo esponenziale molti passaggi per generare un output esponenzialmente più lungo da un dato input).

+0

'Se una determinata espressione regolare genera tutte le stringhe' - La descrizione del problema è piuttosto vaga qui. Non so di cosa stai parlando. – nhahtdh

+0

Grazie per la risposta. Potresti, se vuoi, indagare anche nella seconda parte della mia domanda? – fuz

1

Wikipedia dice: ... if there exists at least one regex that matches a particular set then there exist an infinite number of such expressions. Possiamo dedurre da questa affermazione che esiste un numero infinito di espressioni che descrivono la lingua di tutte le parole eccetto quelle descritte da R.

Anche in questo caso, (come anche @nhahtdh ha cercato di spiegare) l'algoritmo più semplice per rispondere a questa domanda è estendere l'ambito della valutazione al di fuori del contesto del linguaggio delle espressioni regolari stesso. Ovvero: corrisponde alle stringhe che si desidera escludere (che rappresentano un sottoinsieme finito con cui lavorare) utilizzando l'espressione regolare originale e quindi trattare eventuali errori corrispondenti a una corrispondenza effettiva (su un insieme infinito di altre possibilità). Quindi, se il risultato della corrispondenza è negativo, le stringhe candidate sono un sottoinsieme delle soluzioni valide.

+0

'quindi confrontalo con il set finito di candidati che fornisci. Non proprio. Basta provare a far corrispondere la stringa con l'espressione regolare (normale). Se non riesci ad abbinare = una partita. Questo funziona solo se si desidera negare in particolare una regex intera semplice. Non può concatenare. – nhahtdh

+0

@nhahtdh, ho provato a riformulare la risposta. Qualunque cosa, non vedo una vera applicazione della domanda. –

+0

Controlla [questo commento] (http://stackoverflow.com/questions/15337458/is-there-a-way-to-negate-a-regular-expression/15348226#comment21678409_15337458) – nhahtdh

Problemi correlati