Welche Rechenmodelle können durch Grammatiken ausgedrückt werden?

18

Dies ist eine Neuformulierung von Sind Grammatikprogramme? vorher von Vag gefragt und mit vielen Vorschlägen der Kommentatoren.

Inwiefern kann eine Grammatik als Spezifizierung eines Rechenmodells angesehen werden? Nehmen wir zum Beispiel eine einfache kontextfreie Grammatik wie

G ::= '1' -> '0' '+' '1'
      '1' -> '1' '+' '0'
      '2' -> '2' '+' '0'
      '2' -> '1' '+' '1'
      '2' -> '0' '+' '2'
      '3' -> '3' '+' '0'
      '3' -> '2' '+' '1'
      '3' -> '1' '+' '2'
      '3' -> '1' '+' '2'

Unter der Annahme , dass der Parser nicht zwischen differenziert Terminal und Nicht - End - Symbole , wie ich hier gezeigt habe, dann ist es möglich , einfache Arithmetik für Zahlen bis zu 3 durchzuführen.

Nehmen Sie zum Beispiel die Zeichenfolge

"2 + 0 + 1"

Wenn Sie einen LR (1) -Parser für diesen String ausführen, erhalten Sie den folgenden konkreten Syntaxbaum, in dem das Ergebnis der Berechnung im Stammverzeichnis des Baums gespeichert wird:

           '3'
         /  |  \
        /   |   \
      '2'  '+'  '1'
     / | \
    /  |  \
  '2' '+' '0' 

Wenn wir also eine Grammatik als Programm und einen Parsergenerator als Compiler betrachten , können wir dann die Grammatikspezifikationssprache als Programmiersprache betrachten ?

Könnten wir außerdem Turing-complete-Programme erstellen, indem wir Grammatiken angeben , wie Sie Turing-complete-Programme mit Celullar-Automaten oder dem Lambda-Kalkül erstellen könnten ?

In anderen Worten ist es bekannt , dass im Sinne der Erkennung eine Sprache, reguläre Sprachen entsprechen endliche Automaten , kontextfreie Sprachen entsprechen Automaten nach unten drücken , und kontextsensitiven Sprachen entsprechen begrenzte Automaten linear . Wenn wir jedoch Grammatiken als Rechengeräte betrachten (dh Programme im Sinne des obigen Beispiels), wie klassifizieren wir dann die Rechenstärke jeder Grammatikklasse in der Chomsky-Hierarchie?

Wie wäre es auch mit den weniger bekannten Unterklassen von Grammatiken wie

EDIT: Übrigens, das ist ein Trottel zu meiner eigenen Frage, aber ich habe nicht erwähnt, dass ich kein Startsymbol für die Beispielgrammatik angegeben und bei der Notwendigkeit, zwischen Terminals und Nichtterminals zu unterscheiden, von Hand gewinkt habe. Technisch oder traditionell denke ich, dass die Grammatik wahrscheinlich in einer komplizierteren Form wie dieser geschrieben werden müsste (wobei S das Startsymbol und $ das End-of-Stream-Terminal darstellt):

G ::= S -> R0 '$'
      S -> R1 '$'
      S -> R2 '$'
      R0 -> '0'
      R0 -> R0 '+' '0'
      R1 -> '1'
      R1 -> R0 '+' '1'
      R1 -> '1' '+' R0
      R1 -> R0 '+' '1' '+' R0
      R2 -> '2'
      R2 -> R0 '+' '2'
      R2 -> '2' '+' R0
      R2 -> R0 '+' '2' '+' R0
      R2 -> R1 '+' '1'
      R2 -> R1 '+' '1' '+' R0

... nicht, dass es wirklich etwas ändert, aber ich dachte, ich sollte es erwähnen.

EDIT: Etwas anderes, was mir beim Lesen der Antwort von gasche in den Sinn kam, ist, dass jeder Zweig im Baum in meinem Beispiel eine Teilberechnung darstellt. Wenn Sie jede Produktionsregel als eine Funktion betrachten, bei der die LHS das Ergebnis und die RHS die Argumente darstellt, bestimmt die Struktur der Grammatik, wie Funktionen zusammengesetzt sind.

Mit anderen Worten, der Kontext des Parsers zusammen mit seinem Lookahead-Mechanismus hilft dabei, nicht nur zu bestimmen, welche Funktionen angewendet werden sollen (ein bisschen wie parametrischer Polymorphismus), sondern wie sie zusammengesetzt werden sollten, um neue Funktionen zu bilden.

Zumindest könnte man das für eindeutige CFGs so sehen, für andere Grammatiken ist mir die mentale Gymnastik im Moment ein bisschen zu viel.

Rehno Lindeque
quelle
3
Sie haben vergessen, den Visibly Pushdown Automaton (Nested Words) zu erwähnen, ein so schönes und vielversprechendes Gerät! Es ist wichtig, da es eine minimale Verbesserung gegenüber regulären Ausdrücken darstellt, Programme analysieren zu können, die in gängigen Programmiersprachen geschrieben wurden. ( cis.upenn.edu/~alur/nw.html )
Vag
1
Danke, das ist sehr interessant, ich habe es nicht nachgeschlagen! Es gibt noch ein paar andere, die ich übersprungen habe, wie deterministisch, kontextfrei, baumnah, indexiert usw. Ich dachte nur, dass es für eine Frage ein bisschen viel sein könnte ... Aber vielleicht füge ich sie hinzu
Rehno Lindeque
1
@imz Ich meine Grammatiken, wie sie formal in der Chomsky-Hierarchie definiert sind (dh als Produktionen). Da ich genau behaupte, was Sie sagen: Grammatiken sind Programme, bedeutet dies nur die Klasse von Programmen, die durch Grammatiken darstellbar sind (was die Frage ist).
Rehno Lindeque
1
@imz Um ehrlich zu sein, ich kenne mich mit indizierten Grammatiken wirklich nicht aus. Ich habe sie nur als Nachdenken hinzugefügt.
Rehno Lindeque
1
Ich fange an zu denken, dass es eine gute Idee gewesen sein könnte, diese Frage im LtU-Forum zu posten, anstatt sich die coolen Diskussionen anzusehen: P. Btw @imz, vielleicht ist es am besten, die Frage wie folgt zu lesen: "Welche Grammatikklassen entsprechen welchen Programmklassen im funktionalen Sinne, die Jukka in Marc Hammans Antwort beschrieben hat". Vielleicht sollte ich das klarer machen ...
Rehno Lindeque

Antworten:

10

Es gibt eine Eins-zu-Eins-Entsprechung zwischen Chomsky-Typ-0-Grammatiken und Turing-Maschinen.

Dies wird in der Programmiersprache Thue ausgenutzt, mit der Sie Turing-vollständige Programme schreiben können, die durch eine anfängliche Zeichenfolge und einen Satz von Regeln zum Umschreiben von Zeichenfolgen (eine Semi-Thue-Grammatik , die einer Grammatik vom Typ 0 entspricht) festgelegt sind.

AKTUALISIEREN:

Abgesehen von esoterischen "Turing Tar-Pit" -Sprachen wie Thue können verschiedene Mehrzwecksprachen verwendet werden, mit denen der Programmierer seine eigene Syntax erweitern kann, um während der Parsing-Kompilierungsphase eine Turing-vollständige Berechnung durchzuführen.

Sprachen in der Lisp- Familie, insbesondere Common Lisp , sind wahrscheinlich die offensichtlichsten Beispiele, aber im Allgemeinen auch Sprachen mit statischer Typprüfung, die nicht immer angehalten werden müssen, wie C ++ mit Vorlagen , Scala und Qi .

Antonio Valerio Miceli-Barone
quelle
Die Frage betrifft jedoch Dinge, die umgekehrt funktionieren: Man sollte zum Ergebnis nicht durch Umschreiben einer anfänglichen Folge von Symbolen gemäß den Regeln gelangen, sondern das "Ergebnis" der Berechnung, das durch eine Grammatik in dieser Frage definiert wird, ist eine Initiale Symbol, das die "Eingabe" -Sequenz nach den Regeln der Grammatik erzeugen kann.
imz - Ivan Zakharyaschev
2
concat(quote(in),out)TM(in)=out
Ich bin damit einverstanden, dass die Entsprechung zwischen Typ0-Grammatiken und TMs eine gültige Antwort auf die Frage ist (insbesondere, wenn sie auf die Berechnung von Ja / Nein-Funktionen beschränkt ist). Der weitere Vorschlag, ein willkürliches TM mit einer Grammatik zu modellieren, indem eine Konvention eingeführt wird, wie die Eingabe-Ausgabe-Paare dargestellt werden sollen, scheint mir nicht dem beabsichtigten Interesse der ursprünglichen Frage zu entsprechen: (Fortsetzung)
imz - Ivan Zakharyaschev
Ich verstehe es als eine Frage, um genau die vorhandenen Grammatik-Frameworks und die entsprechenden Parser für die Durchführung von Berechnungen auszunutzen, dh die erlaubte Form der Übersetzung zwischen einer Funktion f und einer Grammatik kann nur lauten: Eine Eingabe, die ich analysiert habe, bedeutet S f ( I) = S.
imz - Ivan Zakharyaschev
1
Oberflächlich betrachtet scheint die Programmiersprache Thue nicht in diese Art der Verwendung eines Grammatikrahmens zu fallen: Obwohl sie Umschreibregeln wie eine Grammatik enthält, erfolgt die Berechnung eines Ergebnisses aus einer Eingabe in die Richtung der Regeln, nicht umgekehrt Richtung, wie Rehno will. (Aber vielleicht geht es nur darum, die Richtung der Pfeile in Produktionen zu ändern: Eine "Berechnung als Parser" -Grammatik im Sinne dieses Q in Thue zu übersetzen, könnte nur bedeuten, die Richtungen der Regeln zu ändern, dann das Thue-Programm werden die
Startsymbole
6

Meine Antwort soll nicht formal, präzise und absolut themenbezogen sein. Ich denke, die Antwort von Marc Hamman ist absolut sicher, aber Ihre Frage hat mich zu einem verwandten Thema gebracht.

Grammatiken können als Sonderfälle deduktiver Systeme betrachtet werden: Die Eingabe ist ein Urteil, und der Analysebaum ist eine Ableitung des Urteils oder ein Beweis dafür, dass das Urteil nach den (grammatischen) Regeln gültig ist.

In diesem Sinne könnte sich Ihre Frage auf den Ansatz eines Teils der Community für Logikprogrammierung / Proof-Suche beziehen (ich denke zum Beispiel an Dale Miller ), der besagt, dass die Proof- Suche im Gegensatz zur klassischen Suche einen rechnerischen Inhalt hat Typ / Beweis Theorie Sicht wo Berechnung Beweis Normalisierung ist .

Bemerkung: Wenn ich meine Antwort noch einmal lese, denke ich, dass die Idee, dass "Syntaxanalyse eine Beweissuche ist", hier etwas weit hergeholt ist. Die Beweisrecherche verläuft vielmehr in die andere Richtung: Man geht von einem gegebenen, recht komplexen Urteil aus und erreicht durch die wiederholte Verwendung von Inferenzregeln, die an der Struktur des Beweises arbeiten, hoffentlich einfachere Axiome, die nicht weiter bewiesen werden müssen. Daher wäre es natürlicher, komplexe Urteile in Grammatik als nicht endständig, Atome als endständig und die Beweissuche als Worterzeugungsproblem oder Nicht-Leertest zu sehen.

gasche
quelle
Sehr interessante Bemerkungen. Mein Gehirn ist ein bisschen zu müde, um jetzt eine gute Antwort zu geben, aber in meinem Beispiel stellen die Zweige des Baums im Wesentlichen Teilberechnungen dar, die nach den
Analyseregeln
6

Könnten wir außerdem Turing-vollständige Programme erstellen, indem wir Grammatiken spezifizieren ...?

Ich bin mir nicht sicher, ob ich Ihre Frage richtig verstanden habe, aber wenn Sie nach einer Programmiersprache suchen, die auf einer Art String-Umschreibesystem basiert, sind Sie wahrscheinlich an Refal interessiert , das auf dem Markov-Algorithmus- Formalismus (einem Turing- Algorithmus) basiert. vollständiger Formalismus, der auch ein grammatikalisches System zum Umschreiben von Zeichenketten ist).

Artem Pelenitsyn
quelle
1
Ich habe die Frage folgendermaßen verstanden: Rehno ist daran interessiert, den Boot-Up-Parsing-Prozess (definiert durch eine Grammatik) als Berechnung des Ergebnisses anzusehen. Die Berechnung sollte das Ergebnis aus den Teilen bilden, die in die entgegengesetzte Richtung zu den Produktionsregeln der Grammatik verlaufen. Refals Umschreibungsregeln (IIUC, ähnlich der oben erwähnten Thue-Programmiersprache) würden in die andere Richtung gehen (von der Eingabe bis zum Ergebnis).
imz - Ivan Zakharyaschev
Nun, da ich darüber nachdenke, haben kontextsensitive Grammatiken mehr als ein Symbol auf der linken Seite der Produktionsregeln. Ich denke, es gibt keinen wirklichen praktischen Unterschied. Ein Parser für eine kontextsensitive Sprache wäre ein System zum Umschreiben von Zeichenfolgen, egal wie Sie es betrachten, oder?
Rehno Lindeque
@imz danke für die Klärung der Frage von Rehno. @Rehno „Ein Parser für eine kontextsensitive Sprache wäre ein System zum Umschreiben von Zeichenfolgen, egal wie Sie es betrachten, oder?“ - es ist wahrscheinlich sinnvoll, ja.
Artem Pelenitsyn
Aber werden Refals Umschreibungsregeln nicht deterministisch behandelt? (Oder anders ausgedrückt: Wird Refal bei der Suche nach einem funktionierenden Umschreibungspfad ein Backtracking durchführen?) Wenn wir diesen "Parsing als Berechnungs" -Ansatz mit Umschreibungsregeln in umgekehrter Richtung modellieren möchten, benötigen wir nicht deterministische Regeln. Betrachten Sie eine Grammatik wie S -> A a; S -> B b; A -> 0; B -> 0. Wenn wir dies durch Umkehren der Regeln programmieren, müssen wir verschiedene Regeln für die Verarbeitung 0zur Laufzeit auswählen , um "0a" oder "0b" zu bewerten S.
imz - Ivan Zakharyaschev
6

(Nur ein paar triviale Überlegungen. Könnte ein Kommentar sein, aber zu lang.)

Was Sie beschreiben, sieht tatsächlich so aus, als wäre es eine ganz natürliche Sicht auf das, was eine Sprache ist (im menschlichen Verständnis von "Sprache", ihrem Zweck) und wie eine Grammatik eine Sprache definiert.

Eine Sprache besteht aus (unendlich vielen) korrekten syntaktischen Formen, die interpretiert werden, um die semantischen Werte zu erhalten .

Wenn die Interpretation berechenbar ist, können die syntaktischen Formen einer Sprache als Programme angesehen werden, die die semantischen Werte berechnen.

Wenn wir annehmen, dass eine Sprache als endliches Gerät implementiert ist, können wir diese endliche Repräsentation einer Sprache als "Grammatik" bezeichnen. Nach diesem Verständnis kümmert sich eine Grammatik um die Syntax, aber auch um die Semantik, dh wie der semantische Wert eines ganzen Ausdrucks aus den Werten seiner Teile berechnet wird (die atomaren Teile und ihre Werte werden in einem "Lexikon" gespeichert). .

Einige Theorien der natürlichen Sprache haben eine solche Form (die Form, die mit den obigen Überlegungen übereinstimmt; sie wurde bereits in der Antwort von @ gasche erwähnt): ein deduktives System , das nach einer Ableitung der Eingabe sucht (gekoppelt mit der Berechnung der Semantik) Wert oder die Bildung des Beweisbegriffs (vgl. Curry-Horward-Korrespondenz). Wenn wir also solche Systeme betrachten und sie als Grammatik betrachten, ist Ihre Frage trivial : Diese Systeme sind genau so konzipiert, dass sie Berechnungen in der von Ihnen beschriebenen Weise ausführen.

fGI f(I)=SISG

(Tatsächlich sehen die echten Compiler für Programmiersprachen eher wie ein System mit Syntax und Semantik aus: Sie transformieren die syntaktische Form eines Programms in eine ausführbare Datei, die die semantische Bedeutung des Programms darstellt, und nicht nur in ein Startsymbol der Grammatik.)

imz - Ivan Zakharyaschev
quelle
4

Nur um hinzuzufügen:

Ein reines Logikprogramm hat deklaratives Lesen und prozedurales Lesen. In diesem Bericht wird die Idee erörtert, dass diese durch eine grammatikalische Lesart ergänzt werden können, bei der die Klauseln als Umschreibregeln einer Grammatik betrachtet werden. Ziel ist es zu zeigen, dass diese Sichtweise den Know-how-Transfer von der Logikprogrammierung auf andere Forschungen zu Programmiersprachen und umgekehrt erleichtert. Einige Beispiele für eine solche Übertragung werden diskutiert. Andererseits rechtfertigt die vorgestellte grammatische Sichtweise einige Ad-hoc-Erweiterungen der reinen Logikprogrammierung und erleichtert die Entwicklung theoretischer Grundlagen für solche Erweiterungen.

Eine grammatische Sicht der Logikprogrammierung von Pierre Deransart und Jan Maluszynski.

Vag
quelle
Anscheinend ist Prolog aus Attributgrammatiken entstanden, und diese Sichtweise hat die Logikprogrammierung gestartet.
Reinierpost
1

Was ist mit so etwas wie Peano-Zahlen:

S    -> int
int  -> zero
int  -> succ
zero -> "0"
succ -> "#" int

es wird jede Zeichenfolge (Nummer) dieser Form erkennen:

0   // zero
#0  // one
##0 // two

und es sollte eine verschachtelte Struktur zurückgeben, wobei die Tiefe die Zahl ist.

Aber es wird langsam kompliziert, wenn man nur noch sagen will:

S    -> int
int  -> sum
int  -> zero
int  -> succ
zero -> "0"
succ -> "#" int
sum  -> int "+" int

Es macht durchaus Sinn, dass es nur wohlgeformte Ints wie dieses erkennt:

#####0 + ####0

Diese Grammatik führt jedoch eine Aufteilung des Analysebaums ein, wenn eine Summe vorhanden ist. Anstatt also einen schönen, einseitig verzweigten Baum zu haben, der direkt einer Zahl zugeordnet ist, haben wir die Struktur des Ausdrucks, der noch ein paar Berechnungen von der tatsächlichen entfernt ist Wert. Es erfolgt also keine Berechnung, sondern nur eine Erkennung. Das Problem ist möglicherweise nicht die Grammatik, sondern der Parser. Man kann stattdessen etwas anderes verwenden, idk ... Ein weiterer Punkt, der in den Sinn kommt, ist die Angemessenheit des Grammatikformalismus, um Berechnung auszudrücken. Wenn Sie das Axiom eines Peano betrachten (in Haskell-ähnlicher Notation):

1) Nat = Zero
2) Nat = Succ Nat
3) Sum ( Succ X ) ( Y ) = Succ ( X + Y )
4) Sum Zero X = X

Die dritte Regel besagt ausdrücklich eine Transformation. Könnte sich jemand vorstellen, in einer kontextfreien Grammatikregel die gleiche Bedeutung zu haben? Und wenn ja, wie?

Dader
quelle