Puoi provare a utilizzare gli automi pushdown. Dato un automa pushdown per la lingua originale, ne costruiamo uno per il turno ciclico. Il nuovo automa funziona in due fasi, corrispondenti alla e parte della parola (dove è nella lingua originale). Nel primo stadio, ogni volta che l'automa vorrebbe far scoppiare un non terminale , può invece spingere un non terminale ; l'idea è che alla fine del primo stadio, lo stack contenga, in ordine inverso, i simboli che si trovano nello stack dopo aver letto dall'automa originale. Nel secondo stadio (l'interruttore non è deterministico), invece di spingere un non terminaleyxyxxyAA′xA ′ xA, C'è permesso di pop un non terminale . Se l'automa originale può effettivamente generare lo stack dopo aver letto , allora quello nuovo sarebbe in grado di far apparire esattamente l'intero stack.A′x
Modifica: ecco alcuni dettagli. Supponiamo di avere un PDA con alfabeto , insieme di stati , insieme di stati accettanti , non terminali , stato iniziale e un insieme di transizioni consentite. Ogni transizione consentita ha la forma , il che significa che quando si trova nello stato , dopo aver letto (o , nel qual caso si tratta di una transizione libera), se la parte superiore dello stack è (o , il che significa che lo stack è vuoto), il PDA può (è un modello non deterministico) passare allo stato , sostituendoQ F Γ q 0 ( q , a , A , q ′ , α ) q a ∈ A a = ϵ A ∈ Γ A = ϵ q ′ A α ∈ Γ ∗ΣQFΓq0(q,a,A,q′,α)qa∈Aa=ϵA∈ΓA=ϵq′A con .α∈Γ∗
Il nuovo PDA ha un nuovo non terminale per ogni . Per ogni due stati e , ci sono due stati . Gli stati iniziali (lo stato iniziale effettivo viene scelto in modo non deterministico tra loro tramite -transitions) sono . Per ogni transizione ci sono transizioni corrispondenti e . Ci sono anche altre transizioni.A′A∈Γq,q′∈QA∈Γ∪{ϵ}(q,q′,1),(q,q′,2,A)ϵ(q,q,1)(q,a,A,q′,α)( ( q , q ″ , 2 , B ) , a , A , ( q ′ , q ″ , 2 , B ) , α )((q,q′′,1),a,A,(q′,q′′,1),α)((q,q′′,2,B),a,A,(q′,q′′,2,B),α)
Per ogni transizione , ci sono transizioni , dove e . Per ogni stato finale , ci sono transizioni , dove .( ( q , q ″ , 1 ) , a , B ′ , ( q ′ , q ″ , 1 ) , B ′ A ′ α ) B ∈ Γ ∪ { ϵ }(q,a,A,q′,α)((q,q′′,1),a,B′,(q′,q′′,1),B′A′α)B∈Γ∪{ϵ}q ∈ F ( ( q , q ″ , 1 ) , ϵ , A , ( q 0 , q ″ , 2 , ϵ ) , A ) A ∈ Γ ∪ { ϵ }ϵ′=ϵq∈F((q,q′′,1),ϵ,A,(q0,q′′,2,ϵ),A)A∈Γ∪{ϵ}
Per ogni transizione , ci sono transizioni , dove . Per ogni transizione , ci sono transizioni , dove . Per ogni transizione , esistono "transizioni generalizzate" ; questi sono implementati come una sequenza di due transizioni attraverso un nuovo stato intermedio. Transizioni\ alpha) con( ( q , q ″ , 2 , A ) , a , B ′ , ( q ′ , q ″ , 2 , A ) , B ′ α ) A ∈ Γ ∪ { ϵ } ( q , a , ϵ , q ′(q,a,ϵ,q′,α)((q,q′′,2,A),a,B′,(q′,q′′,2,A),B′α)A∈Γ∪{ϵ}( ( q , q ″ , 2 , B ) , a , A ′ , ( q ′ , q ″ , 2 , A ) , ϵ ) B ∈ Γ ∪ { ϵ } ( q , a , A , q ′ , B ) ( ( q , q ″ , 2(q,a,ϵ,q′,A)((q,q′′,2,B),a,A′,(q′,q′′,2,A),ϵ)B∈Γ∪{ϵ}(q,a,A,q′,B)( q , a , ϵ , q ′ , α ) | α | ≥ 2 ( q , a , A , q ′ , A ) ( ( q , q ″ , 2 ,((q,q′′,2,C),a,B′A,(q,q′′,2,C),ϵ)(q,a,ϵ,q′,α)|α|≥2sono gestiti in modo simile. Per ogni transizione , ci sono transizioni , dove . Le transizioni sono gestite in modo simile. Infine, esiste un unico stato finale e transizioni .(q,a,A,q′,A)B ∈ Γ ′ ∪ { ϵ } ( q , a , A , q ′ , A α ) f ( ( q , q , 2 , A ) , ϵ , ϵ , f , ϵ((q,q′′,2,A),a,B,(q′,q′′,2,A),B)B∈Γ′∪{ϵ}(q,a,A,q′,Aα)f((q,q,2,A),ϵ,ϵ,f,ϵ)
(Potrebbero esserci alcune transizioni che ho perso, e alcuni dei dettagli che sto omettendo sono in qualche modo disordinati.)
Ricordiamo che stiamo cercando di accettare una parola , dove è accettato dal PDA originale. Uno stato significa che siamo allo stadio 1, allo stato , e il PDA originale è allo stato dopo aver letto . Uno stato è simile, dove corrisponde all'ultima che è stata spuntata. Nella fase 1, siamo autorizzati a spingere invece di popping . Lo facciamo per ogni non terminale che viene prodotto durante l'elaborazione di , ma viene visualizzato solo durante l'elaborazione di . Nella fase 2, siamo autorizzati a far scoppiarex y ( q , q ′ , 1 ) q q ′ x ( q , q ′ , 2 , A ) A A ′ A ′ A x y A ′ A A ϵ B ′yxxy(q,q′,1)qq′x(q,q′,2,A)AA′A′AxyA′invece di spingere . Se lo facciamo, dobbiamo ricordare che la parte superiore del magazzino è davvero ; questo vale solo quando non ci sono cose "temporanee" nello stack, che nel PDA simulato è lo stesso del top-of-stack che è o del modulo .AAϵB′
Qui c'è un semplice esempio. Considera un automa per che spinge per ogni e fa apparire per ogni . Il nuovo automa accetta parole di due forme: e . Per parole del primo modulo, fase 1 consiste nello spingere volte'fase 2 consiste di popping volte , spingendo volte , e iniziano volte . Per le parole della seconda forma, per prima cosa premiamo volte A x A y y k x n y n - k x k y n x n - k k A ′ k A ′ n - k A n - k A k A k A n - k A ′ n - k A ′xnynAxAyykxnyn−kxkynxn−kkA′kA′n−kAn−kAkA, quindi pop volte , push volte , passaggio allo stadio 2 e pop volte .kAn−kA′n−kA′
Ecco un esempio più complicato, per il linguaggio delle parentesi bilanciate di vari tipi ("()", "[]", "<>") in modo tale che i discendenti immediati di ciascun tipo di parentesi debbano appartenere a un tipo diverso. Ad esempio, "([] <>)" è OK ma "()" è errato. Per ogni "(", spingiamo se lo stack top-of-non è , per ogni ")", abbiamo pop . Allo stesso modo , sono associati a "[]" e "<>". Ecco come accettiamo la parola ">) ([()] <". ">)", spingendo e alla fase 2. "(", saltandoe ricordando la parte superiore dello stack . Consumiamo "[()]", spingendo e facendo scoppiare ; quando si spingeA A B C C ′ A ′ A ′ A B A B A A B ϵ X ′ B A C ′A AABCC′A′A′ABAB , siamo consapevoli che il "vero" top-of-stack è , e quindi le parentesi quadre sono consentite (non saremmo ingannati da ">) (() <"); quando si preme , poiché il top-of-stack è (che non è o del modulo ), allora sappiamo che è anche il "vero" top-of-stack, e quindi sono consentite parentesi tonde (anche se l'ombra top-of-stack è ). Infine, consumiamo "<" e pop .AABϵX′BAC′