Frasi di permutazione con analisi LR


16

Una frase di permutazione è un'estensione delle definizioni grammaticali standard di contesto (E) BNF: una frase di permutazione contiene n produzioni (o equivalentemente, non terminali) da A 1 a A{UN1,...,UNn}nUN1 . Nella posizione della frase di permutazione, vorremmo vedere ognuna di queste produzioni esattamente una volta, ma non siamo interessati all'ordinamento di questi non terminali.UNn

Per esempio:

S <- X { A, B, C } Y

è equivalente a:

S <- X  A B C  Y
S <- X  A C B  Y
S <- X  B A C  Y
S <- X  B C A  Y
S <- X  C A B  Y
S <- X  C B A  Y

Il concetto sembra essere stato introdotto in "Estensione di grammatiche senza contesto con frasi di permutazione" . Qui viene anche descritto come analizzare queste frasi in tempo lineare usando un parser LL (1).

La carta "Analisi delle frasi di permutazione" descrive un metodo per analizzare le frasi di permutazione usando combinatori di parser. Questi sono gli unici due articoli che ho trovato che parlano di frasi di permutazione e di come analizzarle.

Visto che possiamo facilmente analizzare questo tipo di frasi di permutazione con parser basati su LL (1), la mia ipotesi sarebbe che possiamo fare lo stesso con i parser in stile LR (1). La mia domanda è quindi:

Una grammatica contenente frasi di permutazione può essere analizzata in modo lineare nel tempo nella dimensione della stringa di input usando macchinari LR (1) mantenendo una tabella di dimensioni ragionevoli?

O(|sol|!)

O(2|sol|) ) codificando le frasi nella tabella LR: possiamo avere elementi LR che codificano quali produzioni devono ancora essere viste, e quindi ridurre l'esplosione a tutti i sottoinsiemi delle frasi di permutazione.

Anche se questo è meglio, ovviamente non è abbastanza buono - avere una frase di permutazione di 30 voci renderebbe inutilizzabile la grammatica. C'è ancora una parte dell'analisi LR che non abbiamo ancora toccato, e questa è la vera procedura basata sullo stack utilizzata per l'analisi. Immagino che la memorizzazione dei contatori nello stack possa essere in grado di risolvere il problema, ma non sono sicuro di come farlo.

Attualmente sto implementando un generatore di parser, e nel dominio del problema le frasi di permutazione sarebbero un dono del cielo. Mentre sto usando macchinari LR (1), la domanda di cui sopra è seguita.


La complessità dell'analisi LR (1) è già esponenziale nelle dimensioni della grammatica senza frasi di permutazione --- tranne se si implementa un calcolo "al volo" del parser, ma poi sembra più un parser Earley che come un genuino LR (1) uno.
Sylvain,

2
Per il resto della tua domanda: cstheory.stackexchange.com/questions/4962/… mostra un limite inferiore esponenziale sulla dimensione di un CFG per permutazioni, e dalla solita costruzione polinomiale di CFG da PDA, questo comporta un limite inferiore esponenziale su anche le dimensioni del PDA.
Sylvain,

1
Non avevo guardato il documento su LL (1). In effetti, il parser implementato non è più un PDA. Continuo a non credere all'esistenza di una "tabella di dimensioni ragionevoli", poiché l'appartenenza a grammatiche commutative senza contesto è NP-completa (vedi ad esempio dx.doi.org/10.3233/FI-1997-3112 ), ma è vero che le istanze difficili potrebbero non essere LR (1).
Sylvain,

2
@Sylvain: Puoi approfondire in che modo la domanda 4962 si collega a questa? Nella domanda 4962, la permutazione è fissa per ogni lunghezza di input e le stringhe da permutare cambiano. Nella domanda attuale, non ripariamo la permutazione. Quindi non riesco a vedere alcuna connessione reale tra di loro.
Tsuyoshi Ito,

2
@Tsuyoshito Ito: In LR (1) l'analisi di un DPDA equivalente alla grammatica di input viene prima costruita e quindi eseguita sulla stringa per riconoscerla. Poiché esiste un CFG di dimensioni lineari con frasi di permutazione per ogni linguaggio di permutazione, il documento di Yuval Filmus (che è più completo della sua risposta su cstheory: vedi cs.toronto.edu/~yuvalf/CFG-LB.pdf ) mostra che no tale DPDA può avere dimensioni polinomiali nelle dimensioni della grammatica di input.
Sylvain,

Risposte:


1

Hai mai pensato di convertirlo in un problema semantico? Invece di regole grammaticali per tutte le permutazioni di nonterminali {A, B, C}, hanno semplicemente una regola da riconoscere (A | B | C) ^ 3 insieme a un codice interno speciale che assicura che venga riconosciuto solo uno di ciascuno, altrimenti dichiara un errore. Vorrei inserire una produzione vuota prima della clausola di cui sopra, la cui riduzione innesca l'inizializzazione di tutto ciò che si sta utilizzando per contare A, B e C, e uno dopo, la cui riduzione innesca il controllo del contatore e (se necessario) afferma l'errore. (ovviamente questo potrebbe diventare un po 'complicato se la grammatica è ricorsiva attraverso A, B e / o C)


0

Non penso che uno abbia bisogno di un contatore. In sostanza, basta controllare tutte le permutazioni ma romperle

pseudo-codice:

perm-match(input, pattern)
     if pattern = nil return true

     foreach(rule in pattern)
         if (match(input, rule))
             perm-match(input - matchedpart, pattern - rule)
             break
         end
     end
     return false
end

Ecco un esempio più concreto

Supponiamo che stiamo cercando di far corrispondere qualsiasi permutazione di abcd e la nostra stringa è bcda

  • Passaggio 1: trova il primo simbolo corrispondente. In questo caso è b
  • Passaggio 2: rimuovi quel simbolo dal nostro modello e riduci la stringa: ad esempio, acd e cda rimangono
  • Passaggio 3: ripetere il passaggio 1 sulle nuove stringhe
    • c corrisponde a cda che ci lascia con ad e da
    • una corrispondenza in da che ci lascia con d e d
    • d corrisponde in d che ci lascia con zero in entrambe le stringhe

Quindi vedete questo semplice algoritmo in grado di verificare abbastanza facilmente una permutazione semplicemente confrontando "stringhe" fuori servizio. Si noti che la complessità della funzione è il caso peggiore O (n!) E il caso migliore O (1). In un certo senso stiamo mantenendo il conto memorizzando i simboli per abbinarli in un array. Penserei che questo sarebbe "veloce" in generale poiché nella maggior parte dei casi non si tratterebbe di n molto grandi.


2
Il mio problema è: mio n diventa molto grande - n=50è abbastanza comune. Inoltre, il tuo metodo non si adatta bene alle tecniche di analisi LR standard: queste frasi sono sparse su una grammatica che contiene principalmente frasi non permutative.
Alex ten Brink,
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.