Esistono macchine "piccole" che possono abbinare efficacemente le espressioni regolari?


30

È noto che un'espressione regolare può essere riconosciuta da un automa finito non deterministico di dimensioni proporzionali all'espressione regolare, o da un FA deterministico che è potenzialmente esponenzialmente più grande. Inoltre, data una stringa ed una regular expression , NFA può testare l'appartenenza a tempo proporzionale ae il DFA può testare l'adesione in un tempo proporzionale a. Il rallentamento per l'NFA deriva dal fatto che essenzialmente dobbiamo tracciare gli insiemi di possibili stati in cui potrebbe trovarsi l'automa, e l'esplosione esponenziale per il DFA deriva dal fatto che i suoi stati sono elementi del gruppo di potere degli stati del NFA.r | s | | r | | s |sr|s||r||s|

È possibile riconoscere in modo efficiente (cioè nel tempo meglio di , e spaziare meglio di ) riconoscere le espressioni regolari, se permettiamo di usare macchine più potenti di automi finiti? (Ad esempio, ci sono guadagni di sintonia nel riconoscere le lingue regolari con automi pushdown o macchine contatore?)O ( 2 | r | )O(|r||s|)O(2|r|)


2
Quando dici che "NFA può testare l'appartenenza in un tempo proporzionale a " intendi che una macchina (deterministica) RAM che simula l'NFA in modo ovvio impiega così tanto tempo? Oppure esiste un altro modo per definire il "tempo di esecuzione di un NFA" che non fa riferimento a un altro modello computazionale? (A parte la definizione ragionevole ma non molto utile che dice che il tempo di esecuzione di qualsiasi NFA per la stringa s è | s | .)|S||r|S|S|
Radu GRIGore

Sì, questa è la giusta interpretazione della mia domanda.
Neel Krishnaswami,

2
Quindi mi sembra più naturale semplicemente chiedere questo: esiste un algoritmo (su una macchina RAM) che decide se una stringa è nella lingua definita dall'espressione regolare r che funziona in o ( | s || r | ) tempo e o ( 2 | r | ) spazio? (Soprattutto se si definisce il tempo di esecuzione di automi pushdown anche in termini di una macchina RAM.)Sro(|S||r|)o(2|r|)
Radu GRIGore

1
Non capisco esattamente il problema. L'input è una stringa se un'espressione regolare r, e il problema è decidere se s è nella lingua definita dall'espressione regolare r?
Robin Kothari,

@Robin: sì, tutto qui. Vorrei sapere se è possibile abbinare le espressioni regolari in modo più efficiente rispetto agli automi finiti utilizzando una maggiore potenza di calcolo o se le funzionalità extra (ad esempio stack, RAM) semplicemente non aiutano.
Neel Krishnaswami,

Risposte:


20

È abbastanza facile scambiare tempo per lo spazio, come segue.

Convertire l'espressione regolare a un NFA - di concretezza negli algoritmi di confronto, si suppone che è il numero di NFA Stati, in modo che la O ( r s ) tempo legato per la simulazione direttamente NFA è valido e il tuo O ( 2 r ) lo spazio associato per l'esecuzione del DFA convertito è valido anche ogni volta che si lavora in una RAM in grado di indirizzare tanta memoria.rO(rS)O(2r)

Ora, suddividere gli stati dell'NFA (arbitrariamente) in sottogruppi S i di al massimo r / k indica ciascuno. All'interno di ogni sottoinsieme S i , possiamo indicizzare i sottoinsiemi A i di S i con numeri da 0 a 2 r / k - 1 .KSior/KSioUNioSio02r/K-1

Costruisci una tabella dove i e j sono nell'intervallo da 0 a k - 1 , c è un simbolo di input e A i è (l'indice numerico di) un sottoinsieme di S i . Il valore memorizzato nella tabella è (l'indice numerico di) un sottoinsieme di S j : uno stato y è in T [ i , j , c , A i ] se e solo seT[io,j,c,UNio]iojK-1cUNioSioSjyT[io,j,c,UNio] appartiene a S j e c'è uno stato in A i che passa a y sul simbolo di input c .ySjUNioyc

Per simulare l'NFA, mantenere indici, uno per ogni S i , specificando il sottoinsieme A i degli stati in S i che possono essere raggiunti da alcuni prefissi dell'input. Per ogni simbolo di input c , utilizzare le tabelle per cercare, per ogni coppia i , j , l'insieme di stati in S j che può essere raggiunto da uno stato in A i mediante una transizione su c , quindi utilizzare un binario bit a bit o operazione sugli indici numerici di questi insiemi di stati per combinarli in un singolo sottoinsieme di stati di S jKSioUNioSiocio,jSjAicSj. Pertanto, ogni passaggio della simulazione richiede il tempo e il tempo totale per la simulazione è O ( s k 2 ) .O(k2)O(sk2)

Lo spazio richiesto è lo spazio per tutte le tabelle, ovvero . L'analisi del tempo e dello spazio è valida su qualsiasi RAM in grado di indirizzare quella quantità di memoria e che può eseguire operazioni binarie su parole sufficientemente grandi da indirizzare tale memoria.O(k22r/k)

Il compromesso spazio-tempo che ottieni da questo non corrisponde perfettamente alla simulazione NFA, a causa della dipendenza quadratica da . Ma poi, io sono scettico che O ( r s ) è il momento giusto vincolato per la simulazione NFA: come si fa a simulare un singolo passo della NFA più veloce di guardare tutti i (forse molti) quadratico transizioni permesse da un momento stato attivo in un altro stato? Non dovrebbe essere O ( r 2 s ) ?kO(rs)O(r2s)

In ogni caso, lasciando variare è possibile ottenere limiti di tempo su un continuum tra i limiti DFA e NFA, con meno spazio rispetto a DFA.k


Penso che la tua correzione sia corretta e la tua risposta risponda alla mia domanda. Tuttavia, la domanda che volevo porre è quanto ulteriore potenza computazionale aiuta. (Ad esempio, con un contatore puoi abbinare una stringa nello spazio O (1).) Se non ti dispiace, lascerò la domanda aperta ancora per un po 'più a lungo per vedere se qualcuno conosce la risposta. ...ak
Neel Krishnaswami,

@Neel: se la soluzione di David è la migliore che una macchina RAM possa fare, allora stack, contatori, ecc. Non aiuteranno. (Ma, naturalmente, ha dato solo limiti superiori, non inferiori).
Radu GRIGore

1
Per quanto ne so, la mia soluzione usa "potenza aggiuntiva": si basa su ricerche di tabelle e indici interi, qualcosa che non è disponibile nei modelli DFA o NFA. Quindi non capisco davvero come non risponda a quella parte della domanda.
David Eppstein,

Ecco un modo alternativo per parametrizzare questo. Supponiamo di essere su una macchina RAM con larghezza della parola , dove w lg r . Quindi la simulazione NFA richiede tempo O ( s r 2 ) e spazio O ( r / w ) . La simulazione DFA non è possibile se r w (spazio disponibile insufficiente). La costruzione in questa risposta imposta k r / w e prende O ( s r 2 / w 2wwlgrO(sr2)O(r/w)rwkr/w tempo e utilizza tutto lo spazio disponibile (ovvero qualcosa nelle vicinanze diuno spaziodi 2 w ). Sta fondamentalmente sfruttando il parallelismo dei bit disponibile in una macchina RAM per eseguire la simulazione NFA più velocemente. O(sr2/w2)2w
DW

4

Questa non è una risposta, ma troppo a lungo per un commento. Sto cercando di spiegare perché la domanda, come posta, potrebbe essere difficile da capire.

Ci sono due modi per definire la complessità computazionale per un dispositivo X .

Il primo e più naturale modo è intrinseco . Bisogna dire come il dispositivo X utilizza l'input, in modo da poter esaminare in seguito come la dimensione n dell'input influisce sul tempo di esecuzione del dispositivo. Bisogna anche dire cosa conta come un'operazione (o passaggio ). Quindi lasciamo semplicemente funzionare il dispositivo sull'input e contiamo le operazioni.

Il secondo è estrinseco . Definiamo complessità computazionale per un altro dispositivo Y e poi si programma Y di agire come un simulatore per X . Dal momento che Y può simulare X in diversi modi , dobbiamo aggiungere che dovremmo usare il migliore. Lasciatemi dire lo stesso con altre parole: diciamo che X impiega tempo su un input di dimensione n se esiste un simulatore di X implementato sulla macchina Y che impiega f ( n ) tempo.O(f(n))f(n)

Ad esempio, una definizione intrinseca per NFA afferma che sono necessari n passaggi per elaborare una stringa di lunghezza n ; una definizione estrinseca che utilizza una macchina RAM come dispositivo Y afferma che il limite superiore più noto è probabilmente la risposta di David Eppstein. (Altrimenti sarebbe strano che (1) la migliore implementazione pratica indicata nell'altra risposta non utilizzi l'alternativa migliore e (2) nessuno qui abbia indicato un'alternativa migliore.) Nota anche che in senso stretto il tuo dispositivo X è l'espressione regolare , ma poiché NFA ha le stesse dimensioni, è sicuro che sia il dispositivo X che stai guardando.

Ora, quando si utilizza il secondo tipo di definizione, non ha molto senso chiedersi in che modo la limitazione delle funzionalità del dispositivo X influisce sul tempo di esecuzione. Ha tuttavia senso chiedersi in che modo la limitazione delle funzionalità del dispositivo Y influisce sul tempo di esecuzione. Ovviamente, consentire macchine più potenti Y potrebbe permetterci di simulare X più velocemente. Quindi, se assumiamo una delle macchine più potenti che potrebbero essere implementate (questo esclude le macchine non deterministiche, per esempio) e creiamo un limite inferiore , allora sappiamo che nessuna macchina meno potente potrebbe fare meglio.Ω(f(n))

Quindi, in un certo senso, la risposta migliore che potresti sperare è una prova in qualcosa come il modello di sonda cellulare che la simulazione di un NFA richiede un certo periodo di tempo. (Tieni presente che se prendi in considerazione la conversione da NFA a DFA, hai bisogno di tempo per scrivere il grande DFA, quindi la memoria non è l'unico problema lì.)


4

Anche se credi che non ci sia nulla di nuovo o di vecchio da imparare sulla corrispondenza delle espressioni regolari, dai un'occhiata a uno dei documenti più belli che ho incontrato da molto tempo: un gioco di espressioni regolari di S Fischer, F Huch e T Wilke, ICFP 2010.

(MMT Chakravarty merita il merito per aver raccomandato questo documento.)

EDIT: Il motivo per cui questo documento è rilevante è che descrive una nuova tecnica (basata su Glushkov degli anni '60) che evita di costruire l'intero NFA (per non parlare del DFA) corrispondente al RE. Quello che viene fatto invece assomiglia all'esecuzione di un algoritmo di marcatura simile a quello noto per decidere l'accettazione di una parola da parte di un NFA sull'albero della sintassi di RE. Le misurazioni delle prestazioni suggeriscono che questo è competitivo, anche con la libreria re2 recentemente pubblicata su Google.


Un bel documento da leggere !!
Hsien-Chih Chang 張顯 之

1

Dai un'occhiata a questo articolo di Russ Cox. Descrive un approccio basato su NFA, inizialmente impiegato da Ken Thompson, mediante il quale una stringa di input s può essere abbinata a un'espressione regolare r nel tempo O (| s |. C ) e nello spazio O (| r |. D ), dove c e d sono costanti con limite superiore. L'articolo descrive anche un'implementazione in C della tecnica.


2
Non sono convinto che sia una descrizione accurata dell'articolo. Sembra che stia creando il DFA dalla NFA in base alle necessità e memorizzando nella cache i risultati. Ma la dimensione della cache potrebbe essere esponenziale in r.
David Eppstein,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.