Come creare DFA dall'espressione regolare senza utilizzare NFA?


12

L'obiettivo è quello di creare DFA da un'espressione regolare e l'utilizzo di "Exp regolare> NFA> Conversione DFA" non è un'opzione. Come si dovrebbe fare per farlo?

Ho fatto questa domanda al nostro professore ma mi ha detto che possiamo usare l'intuizione e gentilmente rifiutato di fornire qualsiasi spiegazione. Quindi volevo chiederti.

"Conversione regolare> NFA> Conversione DFA" non è un'opzione perché una tale conversione richiede molto tempo per convertire un'espressione regolare piuttosto complessa. Ad esempio, per un certo regex "regex> NFA> DFA" richiede 1 ora per un essere umano. Devo convertire regex in DFA in meno di 30 minuti.


2
Devi fornire più contesto. Quale algoritmo (informale) stai attualmente utilizzando per tradurre espressioni regolari? Potrebbe essere utile spiegare il processo con un esempio come a(a|ab|ac)*a+. Puoi tradurlo direttamente in un NDFA che riduci in un DFA, oppure puoi normalizzarlo in qualcosa che si associa immediatamente a un DFA.
amon

Devi farlo su esempi specifici con qualsiasi mezzo o devi fornire una procedura generale per essere applicato da un computer?
babou,

Risposte:


18

Dato che vuoi "convertire regex in DFA in meno di 30 minuti", suppongo che tu stia lavorando a mano su esempi relativamente piccoli.

In questo caso puoi usare l'algoritmo di Brzozowski , che calcola direttamente l'automa Nerode di una lingua (che è noto essere uguale al suo automa deterministico minimo). Si basa su un calcolo diretto dei derivati ​​e funziona anche per espressioni regolari estese che consentono l'intersezione e la complementazione. Lo svantaggio di questo algoritmo è che richiede di verificare l'equivalenza delle espressioni calcolate lungo la strada, un processo costoso. Ma in pratica, e per piccoli esempi, è molto efficiente.[1]

Quozienti a sinistra . Let sia un linguaggio di e lasciare che essere una parola. Allora Il linguaggio è chiamato un quoziente di sinistra (o sinistra derivato ) di .A u u - 1 L = { v A u v L } u - 1 L LLUN*u

u-1L={vUN*|uvL}
u-1LL

Automa di Nerode . L' automa Nerode di è l'automa deterministico dove , e la funzione di transizione è definita, per ogni , dalla formula Attenzione a questa definizione piuttosto astratta. Ogni stato di è un quoziente sinistro di di una parola, e quindi è una lingua di . Lo stato iniziale è la lingua , e l'insieme degli stati finali è l'insieme di tutti i quozienti di sinistra diA ( L ) = ( Q , A , , L , F ) Q = { u - 1 L u A } F = { u - 1 L u L } a A ( u - 1 L ) a = a - 1 ( u - 1LUN(L)=(Q,UN,,L,F)Q={u-1L|uUN*}F={u-1L|uL}un'UN

(u-1L)un'=un'-1(u-1L)=(uun')-1L
UNLUN*LL per una parola di .L

L'algoritmo di Brzozowski . Lascia che siano lettere. Si possono calcolare i quozienti di sinistra usando le seguenti formule: un',B

un'-11=0un'-1B={1Se un'=B0Se un'Bun'-1(L1L2)=un'-1L1u-1L2,un'-1(L1L2)=un'-1L1u-1L2,un'-1(L1L2)=un'-1L1u-1L2,un'-1L*=(un'-1L)L*
un'-1(L1L2)={(un'-1L1)L2SI 1L1,(un'-1L1)L2un'-1L2SI 1L1

Esempio . Per , otteniamo in successione: che fornisce il seguente automa minimo. L=(un'(un'B)*)*(Bun')*

1-1L=L=L1un'-1L1=(un'B)*(un'(un'B)*)*=L2B-1L1=un'(Bun')*=L3un'-1L2=B(un'B)*(un'(un'B)*)*(un'B)*(un'(un'B)*)*=BL2L2=L4B-1L2=un'-1L3=(Bun')*=L5B-1L3=un'-1L4=un'-1(BL2L2)=un'-1L2=L4B-1L4=B-1(BL2L2)=L2B-1L2=L2un'-1L5=B-1L5=un'(Bun')*=L3
L'automa minimo

[1] J. Brzozowski, Derivatives of Regular Expressions, J.ACM 11 (4), 481–494, 1964.

Modifica . (5 aprile 2015) Ho appena scoperto che una domanda simile: quali algoritmi esistono per la costruzione di un DFA che riconosce il linguaggio descritto da una data regex? è stato chiesto su cstheory. La risposta affronta in parte i problemi di complessità.


Puoi dire di più sulla complessità di questo algoritmo?
babou,

@babou La conversione di un RE in un DFA è difficile per PSPACE, quindi è sicuramente esponenziale.
jmite,

Questo dovrebbe probabilmente andare nella risposta. L'OP inizia con "le costruzioni standard tramite NFA sono troppo lente" e parte della risposta sembra essere "sfortuna, non c'è davvero una soluzione rapida". Resta da discutere se questo qui sia migliore della costruzione standard. (cc @jmite)
Raffaello

@jmite Sì, me lo aspettavo. Il motivo della mia domanda è perché questo modo di costruire il DFA dovrebbe quindi essere considerato più semplice. (nota: il sistema ha impiegato un giorno intero per avvisarmi della risposta di @ jmite).
babou,

2

J.-E. Pin fornisce la risposta migliore in termini di formalità e completezza, ma penso che ci sia qualcosa da dire per l '"intuizione" a cui il tuo professore sta suggerendo.

Nella maggior parte di questi casi, la cosa più semplice da fare è guardare un'espressione regolare, capire quale linguaggio sta accettando, quindi usare la tua creatività / intelligenza per costruire un DFA che accetta quel linguaggio.

Non esiste un modo semplice per farlo, a parte gli algoritmi forniti da altri, ma ecco alcune linee guida che potrebbero rivelarsi utili.

  1. Chiediti, potrei scrivere un programma che accetta questo RE usando solo variabili intere booleane o molto piccole? Quindi scrivi quel programma e convertilo in un DFA dove c'è uno stato per ogni combinazione di valori.

  2. Cerca parti dell'espressione regolare che sai di poter accettare in modo deterministico, dove sai "Se vedo questo, allora devo abbinare questa parte della RE". Non ce ne saranno sempre tonnellate, ma l'identificazione di queste parti può mostrare le parti che saranno facili da creare un DFA, in modo da poter dedicare più tempo alle parti che richiedono davvero non determinismo.

  3. La costruzione del sottoinsieme per NFA-> DFA non è in realtà così complicata da un algoritmo. Quindi, se si tratta di un compito, non di una domanda d'esame, potrebbe essere più veloce codificare un'implementazione e consentire al programma di convertire NFA in DFA. Se hai usato il tuo codice, non dovrebbero esserci problemi di plagio.

Ricorda che, qualunque cosa tu faccia, qualsiasi tecnica esploderà esponenzialmente nel peggiore dei casi (a meno che non trovi un algoritmo polinomiale per questo, nel qual caso, congratulazioni, hai dimostrato e ora sei un milionario .)P=NP=PSPUNCE

Prova a "guardare avanti", taglia gli angoli quando puoi usare la tua intuizione in luoghi in cui l'algoritmo richiederebbe molti passaggi ma il suo risultato è chiaro.


-2

Anche se questo non è il modo corretto ma funziona il più delle volte.

Primo passo : trova la stringa più piccola che può essere accettata dall'espressione regolare. Secondo passaggio : disegnare gli stati necessari con la transazione della macchina che accetta la stringa minima. Terzo passaggio : per tutti gli stati disegnare le rimanenti transazioni alfabetiche.

Ad esempio: Regular Expression (0 + 1) * 1 "String che termina con 1" Step 1: String più piccola: 1 Step 2: due stati Q0 e Q1. avendo la transazione di 1 da Q0 a Q1. e Q1 è lo stato accettante. Passaggio 3: per lo stato Q0, la transazione Q0 1 è relativa a Q1. Ora esegui 0 transazioni nel Q0 stesso. Per Q1 State, la transazione Q1 1 rimarrà nel Q1. E 0 transazione andrà nel Q0.

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.