Die meisten Menschen vermeiden es, genau zu beschreiben, was eine syntaktische Kategorie ist, denn wenn Sie es mit allen Details richtig machen, ist das Verhältnis von Einsicht zu notwendiger mathematischer Raffinesse sehr, sehr gering. John Reynolds 'Buch Theories of Programming Languages enthält eine der umfassenderen Erklärungen in Kapitel 1, ebenso wie Robert Harpers Practical Foundations of Programming Languages .
Die Intuition, die Sie haben sollten, ist, dass eine syntaktische Kategorie die Menge von Bäumen ist, die durch eine kontextfreie Grammatik erzeugt werden. Wenn eine solche Definition für eine Gruppe von Bäumen gegeben ist, können Sie Funktionen in dieser Gruppe mithilfe der strukturellen Rekursion definieren und Eigenschaften über diese mithilfe der strukturellen Induktion nachweisen : dh indem Sie alle verschiedenen Arten der Baumkonstruktion analysieren.
Nehmen wir zum Beispiel an, wir haben eine Sprache der arithmetischen Operationen, die durch die folgende Grammatik gegeben ist:
e ::= zero | succ(e)| add(e, e)
Dann können wir eine Interpretationsfunktion definieren, eval
die einen Begriff nimmt und Ihnen eine Ganzzahl gibt, anhand von Fällen, wie wir einen Begriff konstruieren können:
eval : Expr -> Int
eval zero = 0
eval succ(e) = 1 + eval e
eval add(e, e') = eval e + eval e'*
Beachten Sie, dass wir diese Funktion vollständig definiert haben, indem wir eine Klausel für jede mögliche Art und Weise angeben, wie wir einen Ausdruck aus der Grammatik generieren könnten. Die Tatsache, dass dies eine vollständige Definition einer Funktion ist, wird als Prinzip der strukturellen Rekursion bezeichnet .
Wir können Eigenschaften dieser Funktion auch durch strukturelle Induktion nachweisen - indem wir für jeden Fall eine induktive Analyse durchführen. Zum Beispiel können wir für jeden beweisen e
, eval e ≥ 0
.
Proof. By structural induction on e.
- Case e = zero:
By the definition of eval, eval zero = 0.
We know 0 ≥ 0 by reflexivity of ≥.
- Case e = succ(e'):
By induction, we know that eval e' ≥ 0
So we also know that 1 + eval e' ≥ eval e'.
By transitivity, 1 + eval e' ≥ 0.
But eval succ(e') = 1 + eval e'.
So eval succ(e') ≥ 0.
- Case e = add(e', e'').
By induction, we know that eval e' ≥ 0.
By induction, we know that eval e'' ≥ 0.
By properties of addition, we know that eval e' + eval e'' ≥ 0.
By the definition of eval, eval add(e',e'') = eval e' + eval e''.
So eval add(e',e'') ≥ 0.
Die Tatsache, dass nur die Fälle betrachtet werden, in denen Ausdrücke gebildet werden könnten, stellt einen Beweis dar, wird als Prinzip der strukturellen Induktion bezeichnet .
Nun ist es eine Tatsache, dass man Funktionen durch strukturelle Rekursion definieren und Eigenschaften durch strukturelle Induktion für jede Grammatik beweisen kann . Um dies konsequent zu beweisen, ist jedoch ein gewisses Maß an Kategorietheorie erforderlich. Sie müssen syntaktische Kategorien als Anfangsalgebren einer bestimmten Klasse von Funktoren formalisieren und dann beweisen, dass solche Anfangsalgebren für diese Klasse immer existieren.
Dies ist ein wirklich schweres Werkzeug, um solch ein "offensichtliches" Ergebnis zu beweisen. Ich empfehle daher, nur Ihrer Intuition zu vertrauen, wie strukturelle Definitionen funktionieren, und sich dann nur dann mit ihrer detaillierten Semantik zu beschäftigen, wenn Sie sich entscheiden, ein professioneller Logiker zu werden.