Kapitel 3 Spezifikation von Datentypen Logische Strukturen 13.+14. Vorlesung Martin Dietzfelbinger Hintergrund: Behandlung des Bereichs in der AuP-Vorlesung. 29. Juni/13. Juli 2010 Wollen (z.B.) spezifizieren: Stack/Keller of N. Operationen: new, push, pop, top, isempty, wie in der AuD-Vorlesung. Exemplarisch für Softwareentwurf “im Kleinen“. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 1 Beispiel aus der AuD-Vorlesung: 3.1 Einführung, Beispiele, Grundbegriffe Spezifikationsmethoden: Wir verwenden immer Trennung von Syntax und Semantik. 1. Teil einer Spezifikation ist immer die Signatur. Auflistung der Namen aller Sorten. Auflistung der Namen aller Operationen sowie der Sorten der Eingabekomponenten und der Ausgabe. 1. Signatur: Sorten: Elements Stacks Boolean Operationen: new : → Stacks push: Stacks × Elements → Stacks pop: Stacks → Stacks top: Stacks → Elements isempty : Stacks → Boolean Rein syntaktische Vorschriften! Verhalten (noch) ungeklärt! FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 2 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 3 Wie Verhalten“ spezifizieren? Welche Ziele sind zu erreichen? ” • Korrektheit der Spezifikation überprüfbar (Entspricht sie dem, was man sich vorstellt, was der Kunde“ ” wünscht . . . ?) • Korrektheit eine Implementierung überprüfbar • Automatische Entwurfshilfen einsetzbar (schnelle Generierung von Prototypen etc.) • umgangssprachlich: zu unpräzise • Exemplarische imperative Spezifikation“: ” Konkrete Implementierung. Zu wenig abstrakt, keine Flexibilität, Korrektheitsbeweise alternativer Implementierungen praktisch unmöglich, Verständlichkeit fraglich. • Axiomatische imperative Spezifikation“: ” Zusicherungskalkül (Vorbedingung/Nachbedingung), z.B.: {true} push(s, x) {s = Λ ∧ top(s) = x} {s = s} push(s, x); pop(s){s = s} Eigenschaften: • Verständlichkeit (für eingearbeiteten Experten) • Eindeutige Semantik • Abstraktion keine irrelevanten Details, keine frühe Festlegung auf mächtig, interessant, anderes Thema konkrete Implementierung FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 4 • Exemplarische applikative Spezifikation“: ” das mathematische Modell“ aus der AuD-Vorlesung ” Stacks: Die Menge der Tupel (a1, . . . , an) ∈ Seq(D). 5 (Für weitere Beispiele siehe AuP-Vorlesung!) Boolean: {w , f }. Idee: Eine Implementierung ist dann korrekt, wenn ihr E/AVerhalten zu dem des mathematischen Modells identisch ist. Im Prinzip gut verständlich. Korrektheitsbeweise eher umständlich und nicht automatisierbar. (Benötige geschickte Induktionsbehauptung.) LS – 29.06.+13.07.2010 LS – 29.06.+13.07.2010 • Axiomatische applikative Spezifikation“: ” Gleichungen beschreiben das Verhalten der Objekte. push((a1, . . . , an), a) = (a, a1, . . . , an) usw. FG KTuEA, TU Ilmenau FG KTuEA, TU Ilmenau 6 isempty(push(s, x)) = f isempty(new ) = w top(push(s, x)) = x pop(push(s, x)) = s Dieser Ansatz führt zu einem Gleichungskalkül. Die Implementierung ist völlig frei. Für die Korrektheit wird nur verlangt, dass die Axiome erfüllt“ werden. ” Übung: Zeige dies für die beiden geläufigen Implementierungen von Stacks, mit Listen und mit Arrays. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 7 Hier soll geklärt werden, was eine Spezifikation eigentlich bedeuten“ soll. ” Ein Modell für eine Spezifikation besteht aus Mengen, die die Sortennamen interpretieren sowie aus Funktionen (mit den korrekten und Eingabesorten), die die Operationsnamen interpretieren. Im Zusammenhang von Datentypen spricht man nicht von einem Modell, sondern von einer Algebra. Man verlangt, dass die Spezifikation erfüllt“ ist. ” Aber das ist nicht alles: Es kann viele Algebren geben, die eine Spezifikation erfüllen. Welche ist gemeint? Beispiel: Bei Stacks könnte man folgendes mathematische Modell betrachten: new () = () (leere Folge, ∅) push(s, x) = (s, x) (geordnetes Paar) top((s, x)) = x, top(()) = undefiniert pop((s, x)) = s, top(()) = undefiniert isempty((s, x)) = f , isempty(()) = w . Als Interpretation der Sorte stacks hätte man die Menge aller geschachtelten Paare (((. . . (((), an), an−1), . . . ), a2), a1), für n ≥ 0, a1, . . . , an ∈ D Auch dies liefert eine Algebra, die die Axiome erfüllt, und die das gleiche E/A-Verhalten hat wie unser Standardmodell. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 8 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 Fragen: Mittel der Logik: • Widerspruchsfreiheit – Gibt es überhaupt eine Algebra zu einer axiomatischen Spezifikation? • Funktionszeichen (kennen wir) • Vollständigkeit – Lassen sich alle vom Datentypen gewünschten Eigenschaften folgern, d.h. gelten sie immer, wenn die Axiome gelten? 9 • Terme (kennen wir) • Gleichungen (neu!) • Eindeutigkeit – Sind alle Modelle im wesentlichen“ gleich? ” (Nein!) • Kann man eine Klasse von relevanten“ Modellen finden, ” die man durch Axiome eindeutig beschreiben kann? (Oft ja, manchmal nein.) FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 10 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 11 Definition 3.1.1 Eine Signatur Σ besteht aus einer endlichen Liste von Sor” ten“ (d.h. Sortennamen) und einer endlichen Liste von Operationen“ ” (d.h. Operationsnamen mit Angabe von Definitionsbereich und Wertebereich; Definitionsbereich: kartesisches Produkt von Sortennamen; Wertebereich: ein Sortenname) FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 12 Beispiel Boolean“: ” bool sorts bool ops true : → bool (nullstellig) false : → bool (nullstellig) neg : bool → bool (einstellig) and : bool × bool → bool (2-stellig) or : bool × bool → bool (2-stellig) ite : bool × bool × bool → bool (3-stellig) Nur eine Sorte: einsortig“. ” ite“: if a then b else c, für Wahrheitswerte: (a ∧ b) ∨ (¬a ∧ c). ” FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 Beispiel Natürliche Zahlen“, ebenfalls einsortig: ” nat sorts nat ops null : → nat succ : nat → nat Mit Import“: ” nat1 bool + nat + (gemeint: Sorten und Operationen abschreiben“) ” ops add : nat × nat → nat le : nat × nat → bool Mehrsortig“ ” le“: Wird später als ≤“ interpretiert. ” ” Stacks über natürlichen Zahlen“ ” natstacks nat1 + sorts stack ops new : → stack push : stack × nat → stack pop : stack → stack top : stack → nat isempty : stack → bool FG KTuEA, TU Ilmenau FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 14 LS – 29.06.+13.07.2010 13 15 Definition 3.1.1 Queues über natürlichen Zahlen“ ” natqueues nat1 + sorts queue ops new : → queue enq : queue × nat → queue deq : queue → queue first : queue → nat isempty : queue → bool Die Menge T (Σ) der Terme über Σ (mit/ohne Variable) und die Ausgabesorte dieser Terme ist wie folgt induktiv definiert: (i) Konstante (nullstellige Operationsnamen) op sind Terme, ihre Ausgabesorte s ergibt sich aus der Signaturzeile op : · · · → s. (i’) [in der Version mit Variablen“: Variable x1, x2, . . . sind ” Terme, jeder Variablen ist eine Sorte zugeordnet.] (ii) Wenn op : s1 × · · · × sk → sk+1 eine Zeile in Σ ist und t1, . . . , tk Terme mit Ausgabesorten s1, . . . , sk sind, dann ist op(t1, . . . , tk ) Term mit Ausgabesorte sk+1. Strukturell identisch zur Signatur von Stacks! FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 16 Beispiele: nat-Terme: null , succ(null ), succ(succ(null )) usw. natstack -Terme: Term new push(new , null ) push(new , succ(null )) pop(push(new , succ(null ))) top(push(new , succ(null ))) isempty(push(new , succ(null ))) Ausgabesorte stack stack stack stack nat bool Beachte: Terme sind Texte, sie bedeuten (bisher jedenfalls) nichts. Idee (neu im Vergleich zur Prädikatenlogik): Wir beabsichtigen: top(push(new , succ(null ))) = “ succ(null ). ” FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 Gegeben sei eine Signatur Σ. 18 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 17 Spezifikation des Verhaltens durch Gleichungen ( Axiome“): ” Beispiel Boolean“: ” bool vars p, q : bool (Variable der Sorte bool ) axs ite(true, p, q) = p ite(false, p, q) = q neg(p) = ite(p, false, true) and (p, q) = ite(p, q, false) or (p, q) = ite(p, true, q) Nur eine Sorte: einsortig“. ” ite“: if a then b else c, für Wahrheitswerte: (a ∧ b) ∨ (¬a ∧ c). ” Implizit: Die freien Variablen sind ∀-quantifiziert. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 19 Beispiel Natürliche Zahlen“: ” nat1 bool + nat+ (gemeint: auch Variable und Axiome abschreiben“) ” vars n, m : nat axs le(null , n) = true le(succ(n), null ) = false le(succ(n), succ(m)) = le(n, m) Beispiel Stacks über den natürlichen Zahlen“: ” natstacks nat1 + vars s : stack ; n : nat axs pop(push(s, n)) = s top(push(s, n)) = n In Implementierung: Fehler! pop(new ) = new top(new ) = null In Implementierung: Fehler! Das Unterdrücken des Ergebnisses undefiniert“ vermeidet ” Komplikationen und Fallunterscheidungen. Könnte aber im Prinzip hier ebenfalls benutzt werden. Partiell definierte Operationen“. ” FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 20 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 Beispiel Queues über den natürlichen Zahlen“: ” natqueues nat1 + vars q : queue; n : nat In Implementierung: Fehler! axs deq(new ) = new deq(enq(new , n)) = new deq(enq(enq(q, n), m)) = enq(deq(enq(q, n)), m) In Implementierung: Fehler! first(new ) = null first(enq(new , n)) = n first(enq(enq(q, n), m)) = first(enq(q, n)) Definition 3.1.2 FG KTuEA, TU Ilmenau FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 22 21 Eine Signatur Σ, eine Liste X von Variablennamen (mit Sorten) und eine Liste axs von Gleichungen t1 = t2 zwischen Termen der gleichen Sorte heißt eine Spezifikation (eines Datentyps). Wir schreiben (Σ, X, axs) oder (Σ, axs) (wenn es keine Variablen gibt oder ihre Namen nicht wichtig sind). LS – 29.06.+13.07.2010 23 Wir definieren die Semantik für Spezifikationen. Beispiel: bool . Wann passt eine Struktur zu einer Signatur? Σ-Algebren: Definition 3.1.3 1) {0, 1} mit true A, false A, and A, or A, ite A, neg A in der Standard-Weise definiert. Sei Σ eine Signatur. Eine Σ-Algebra A (eine zu Σ passende Struktur) ist definiert durch eine Liste (sA, s Sorte in Σ, von nichtleeren Mengen, und für jeden in Σ angegebenen Operator op : s1 × · · · × sk → sk+1 eine Funktion 2) {0, 1}n mit true A = (1, . . . , 1) und false A = (0, . . . , 0), sowie and A, or A, ite A, neg A komponentenweise definiert. opA : (s1)A × · · · × (sk )A → (sk+1)A. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 24 Um zu sehen, ob in A Axiome erfüllt“ sind, müssen wir ” Σ-Terme auswerten. Für die Variablen benötigen wir wieder Belegungen ξ. Beispiel: bool mit Variablen p, q. Als Σ-Algebra betrachten wir {0, 1}n mit komponentenweisen Operationen. ξ(p) = (0, 1, 0, 1, 0, . . . , 0), ξ(q) = (1, 1, 0, 0, 0, . . . , 0). 3) ( die triviale Algebra“) ” {0}, alle Funktionen haben als Wert 0. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 25 Definition 3.1.4 (a) Eine Σ-Struktur α = (A, ξ) für eine Spezifikation (Σ, X, axs) besteht aus einer Σ-Algebra A und einer Funktion ξ, die jede Variable x ∈ X von der Sorte s auf ein Element der Menge sA abbildet. (b) Dann definieren wir induktiv: (i) α(op) = op A ∈ sA, für nullstellige Operatoren op der Sorte s. α(or (q, p)) soll or A(ξ(p), ξ(q)) = (1, 1, 0, 1, 0, . . . , 0) sein. (ii) α(x) = ξ(x), für Variable x ∈ X. (iii) α(op(t1, . . . , tk )) = op A(α(t1), . . . , α(tk )). FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 26 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 27 Definition 3.1.4 (Forts.) (c) Eine Gleichung t1 = t2 zwischen zwei Termen von derselben Ausgabesorte gilt in A, wenn für alle Strukturen α = (A, ξ), die die Variablen belegt, die in t1 und t2 vorkommen, gilt: α(t1) = α(t2). Beispiel: natstack . Wir beschreiben die Standard-Algebra. Sorten: bool A = {w , f } true A = w , false A = f neg A(w ) = f , neg A(f ) = w ; andere boolesche Operationen wie üblich. nat A = N (Freie Variable sind hier stillschweigend mit ∀ quantifiziert.) Wir schreiben dann: A |= t1 = t2. Man kann in solchen Strukturen auch allgemeinere Formeln betrachten, mit Gleichungen als Primformeln und darauf aufgebauten komplexeren Formeln wie in der Prädikatenlogik. Wird hier nicht betrachtet. (d) (Σ, X, axs) sei eine Spezifikation. Eine Σ-Algebra A erfüllt (Σ, X, axs), wenn A |= t1 = t2 für alle Gleichungen t1 = t2 in axs gilt. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 28 Operationen: FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 29 Proposition 3.1.5 null A = 0 succ A(n) = n + 1 für n ∈ N Die eben beschriebene Σ-Algebra erfüllt alle Axiome für die Spezifikation natstack . add A(n, m) = n + m für n, m ∈ N (Simples Nachkontrollieren!) le A(n, m) = w falls n ≤ m, sonst le A(n, m) = f natstack A = {(a1, . . . , ak ) | k ≥ 0, a1, . . . , ak ∈ N} Gibt es andere Strukturen für natstack ? new A() = () (leere Folge) Ja! push A((a1, . . . , ak ), a) = (a, a1, . . . , ak ) (Zum Beispiel die triviale Algebra, in der jede Sortenmenge die Menge {0} ist.) pop A((a1, . . . , ak )) = (a2, . . . , ak ), falls k ≥ 1, bzw.= () falls k=0 top A((a1, . . . , ak )) = a1, falls k ≥ 1, bzw. = 0 falls k = 0 isempty A((a1, . . . , ak )) = f , falls k ≥ 1, bzw. = w falls k = 0 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 30 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 31 (1) Implementierung in Programmiersprachen durch Listen. stellung des Nachfolgers. Sorten: bool A = {0, 1} nat A = Menge der Binärdarstellungen der natürlichen Zahlen (etwas idealisiert: keine Längenbeschränkung) natstack A = Menge aller linearen Listen mit Einträgen aus nat A. add A(w, v) = u für Binärdarstellungen w, v, u, wobei u die Summe von w und v darstellt. le A(w, v) entsprechend. (Abstrakt gedacht: Die konkrete Lage im Speicher spielt keine Rolle.) Operationen: true A, false A, neg A etc.: wie üblich. null A = 0 succ A(w) = w+ für w eine Binärdarstellung, w+ die BinärdarFG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 32 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 33 new A() = leere Liste (2) Implementierung in Programmiersprachen durch Arrays. push A(L, a) = Resultat, wenn a vorne an Liste L angefügt wird Idealisiert: Arrays sind unendlich lange, Einträge sind Binärdarstellungen beliebiger Länge, alle bis auf endlich viele Arrayeinträge sind 0. pop A(L) = Resultat, wenn aus L das erste Listenelement gestrichen wird; wenn L leer ist: die leere Liste. new A() = (T, p), Array T mit lauter Null-Einträgen, Indexmenge N+, Pegel p = 0. top A(L) = Eintrag im ersten Element von L, wenn dieses existiert; wenn L leer ist: 0. isempty A(L) = 1, falls L leer, bzw. = 0 falls L nichtleer. push A((T, p), a) = Resultat, wenn man p++; T [p] ← a ausführt. pop A((T, p)) = (T, p − 1), falls p > 0. Falls p = 0: (T, 0). top A((T, p)) = T [p], falls p > 0, bzw. = 0, falls p = 0. isempty A((T, p)) = 1, falls p > 0, bzw. = 0, falls p = 0. Besonderheit: Bei pop werden Einträge nicht gestrichen. Das führt dazu, dass in T die Historie (teilweise) aufbewahrt wird. Dennoch: Korrektheit bezüglich der Axiome gilt, wenn man stets nur das Teilarray T [1..p] betrachtet. Es ist leicht, nachzukontrollieren, dass die Stack-Axiome durch diese Algebra erfüllt sind. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 34 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 35 (3) Legal, aber unerwünscht: 3.2 Das initiale Modell bool A = nat A = natstack A = {0} Bei Stacks und Queues glauben wir zu wissen, was gemeint ” ist“. Hier wird dies präzise gefasst. Alle Operationen liefern stets den Wert 0. Das triviale Modell“. ” Beobachtung: Jede Spezifikation mit Axiomen, die nur aus Gleichungen bestehen, wird durch ein solches triviales Modell erfüllt. Vermengt, was es unterscheiden sollte: confusion“. ” (Σ, X, axs) sei eine Spezifikation. TΣ0 := Menge der variablenfreien Terme zu Σ. ( Grundterme“). ” Wenn es für eine Sorte keinen Grundterm gibt, erfindet man eine neue nullstellige Funktion für eine solche Sorte, und bildet damit neue Grundterme. Gegebenenfalls wiederholen. Jede Algebra A für Σ gibt jedem Grundterm t ∈ TΣ0 (Sorte s) einen Wert α(t) in seiner Sortenmenge sA. (Genauer: α = (A, ξ) wobei ξ die leere Funktion ist.) s0A := {α(t) | α = (A, ∅), t Grundterm der Sorte s} FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 36 A0 ist die Σ-Algebra, die diese Mengen als Sortenmengen hat, die Operationen werden von sA übernommen. Es ist klar, dass Anwenden von Operationen auf beliebige Elemente der Sortenmengen s0A immer wieder solche Elemente liefert. Also ist A0 tatsächlich selber eine Σ-Algebra. Man kann zeigen: A0 ist die kleinste Unteralgebra“ von A. ” (Operationen aus A übernommen, Sortenmengen möglichst klein.) FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 37 Beispiel: Die Algebra A mit Grundmenge bool A = {0, 1}n ist zwar interessant, aber nicht minimal. Grundterme: true, false bool 0A = {α(true), α(false)} = {(0, . . . , 0), (1, . . . , 1)}. Elemente von bool A = {0, 1}n, für die es keinen Grundterm gibt, zählen als junk“ und fallen in der kleinsten Unteralgebra ” heraus. Alle Objekte in A werden durch einen Term beschrieben! Weiter gilt: Aus A |= (Σ, axs) folgt A0 |= (Σ, axs). (In den Axiomen werden Allquantoren ergänzt, und wenn etwas für alle Elemente in A gilt, dann erst recht für alle Elemente in A0.) Beachte: Für die Definition von A0 |= (Σ, axs) werden selbstverständlich Variable und Belegungen benötigt! FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 38 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 39 Die initiale Σ-Algebra zu (Σ, axs): Definition 3.2.1 Jedes Element in einer Sortenmenge soll durch einen Term beschrieben werden, das Modell soll minimal“ sein ( no junk“). ” ” Erinnerung: Herbrand-Modelle hatten als Elemente genau die Grundterme, dabei stand jeder Term für sich selbst. Gegeben sei eine Spezifikation (Σ, X, axs). Da aber (z.B.) top(push(push(new , null ), succ(null ))) und succ(null ) doch irgendwie gleich“ sein sollen, ist dieser Ansatz hier nicht ” ausreichend. Durch verschiedene Terme beschriebene Objekte sollen dann, aber auch nur dann gleich“ sein, wenn dies aus den Axiomen ” beweisbar“ ist ( no confusion“). ” ” ??? Wir brauchen einen Term-Transformationskalkül. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 40 Gegeben sei eine Spezifikation (Σ, X, axs). Wir definieren induktiv eine Relation ≡ auf der Menge TΣ0 der Grundterme, wie folgt: (i) t1 ≡ t2, falls t1 → t2 oder t2 → t1 oder t1 = t2. (ii) Wenn t1 ≡ t2 und t2 ≡ t3, dann t1 ≡ t3. ( Transitiver Abschluss“.) ” (iii) Wenn t1 ≡ t1,. . . , tk ≡ tk für Termpaare der Sorten s1, . . . , sk und op : s1 × · · · × sk → sk+1 Operation in Σ ist, dann op(t1, . . . , tk ) ≡ op(t1, . . . , tk ). ( Einsetzungs-Abschluss“.) ” LS – 29.06.+13.07.2010 t1 = t01[x1|t1, . . . , xk |tk ] und t2 = t02[x1|t1, . . . , xk |tk ]. Beispiel: top(push(push(new , null ), succ(null ))) → succ(null ) pop(push(push(new , null ), succ(null ))) → push(new , null ) FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 41 Beispiel: Definition 3.2.2 FG KTuEA, TU Ilmenau Für Terme t1 und t2 schreiben wir t1 → t2, falls es ein Axiom t01 = t02 gibt, das freie Variable x1, . . . , xk ∈ X enthält, und wenn es Grundterme t1, . . . , tk gibt, so dass 42 Aus Axiom: pop(push(push(new , null ), succ(null ))) push(new , null ) ≡ Einsetzen: top(pop(push(push(new , null ), succ(null )))) ≡ top(push(new , null )) Aus Axiom: top(push(new , null )) ≡ null . Transitivität: top(pop(push(push(new , null ), succ(null )))) ≡ null Man erhält einen Termersetzungskalkül“. ” Grundregel: Wenn ein Teilterm das Muster eines Axioms erfüllt, darf man ihn durch den entsprechend dem Axiom transformierten Term ersetzen, wie in Definition 3.2.1. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 43 Beobachtung: ≡ ist Äquivalenzrelation auf TΣ0 . (Transitivität und Reflexivität erzwungen, Symmetrie leicht nachzuweisen, mit Regel (i) als Induktionsanfang.) Häufig: Durch systematische Transformation kann man Grundterme in eine Normalform“ bringen – nicht für jede Spezifi” kation, aber in wichtigen Fällen. Klar: Wenn t ≡ t, dann haben t und t dieselbe Sorte. (Unsere Spezifikationen gehören alle dazu.) Beispiel: neg(or(true, neg(and(true, false)))) Wir bilden Äquivalenzklassen [t] = {t | t ≡ t}. Dadurch wird jede Teilmenge von TΣ0 , die zu einer Sorte gehört, in Klassen zerlegt. Oder im Fall der Queue: Abkürzungen 0, 1, 2, . . . für null, succ(null), . . . Idee: Mache diese Äquivalenzklassen zu Objekten einer ΣAlgebra. enq(new, first(deq(enq(enq(enq(new, 5), 3), 6)))) FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 44 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 Definition 3.2.3 Satz 3.2.4 Gegeben sei eine Spezifikation (Σ, X, axs). Für jede Spezifikation (Σ, X, axs) gilt: A∗Σ |= (Σ, X, axs). A∗Σ ist die folgende Algebra (auch TΣ0 / ≡ genannt; der Vorgang heißt Quotientenbildung): Beweis: t1 = t2 sei Axiom mit Variablen x1, . . . , x ∈ X. ξ : X → s Sorte sA∗Σ sei Belegung. Für jede Sorte s definiere sA∗Σ := {[t] | t Term der Sorte s}. Für jede Operation op : s1 × · · · × sk → sk+1 und alle Terme t1, . . . , tk der Sorten s1, . . . , sk definiere op A∗ ([t1], . . . , [tk ]) := [op(t1, . . . , tk )]. Σ Wohldefiniertheit“: Muss checken: ” t1 ≡ t1, . . . , tk ≡ tk ⇒ op(t1, . . . , tk ) ≡ op(t1, . . . , tk ). 45 Jedes ξ(xj ) ist eine Klasse [tj ] (der richtigen Sorte). Zu zeigen: α(t1[x1|t1, . . . , x|t]) = α(t2[x1|t1, . . . , x|t]). Dazu zeigt man, ähnlich wie beim Substitutionslemma: α(t1[x1|t1, . . . , x|t]) = [t1[x1|t1, . . . , x|t], analog für t2, und verwendet, dass t1[x1|t1, . . . , x|t] ≡ t2[x1|t1, . . . , x|t]. Dies gilt direkt nach der Definition von ≡. FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 46 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 47 Zusätzliche spezielle Eigenschaft: Initialität“. ” Behauptung 3.2.5 Vorsicht: Wenn A |= (Σ, X, axs), dann existiert eine Familie Φ = (Φs)s Sorte mit: Φs : sA∗ → sA, so dass Φ ein Σ-Algebra-Homomorphismus ist, d. h. für Operationen op : s1 × · · · × sk → sk+1 in Σ und Grundterme t1, . . . , tk gilt: Die Abbildungen Φs müssen nicht surjektiv sein, sie erfassen nur den durch Terme benannten Teil von sA, also A0. Restlicher Teil von sA: junk“. ” Die Abbildungen Φs müssen auch nicht injektiv sein. In diesem Fall werden in A Terme identifiziert, ohne dass dies von den Axiomen erzwungen wird ( confusion“). ” Φsk+1 (opA∗ ([t1], . . . , [tk ])) = opA(Φs1 ([t1]), . . . , Φsk ([tk ])). FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 48 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 49 Beweis der Behauptung: Definition 3.2.6 Man definiert Eine Σ-Algebra A∗ heißt initial für die Spezifikation (Σ, X, axs), falls für jedes Modell A von (Σ, X, axs) ein eindeutig bestimmter Σ-Algebra-Homomorphismus Φ : A∗ → A existiert. Φs([t]) := α(t) für Grundterme t der Sorte s. Für die HomomorphieEigenschaft zeigt man: t ≡ t ⇒ α(t) = α(t). Haben: A∗Σ ist initial. (Methode: Induktion über die Definition von ≡. Hier nicht ausgeführt.) FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 50 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 51 Satz 3.2.7 ∗ Definition 3.2.8 ∗∗ Wenn A und A beide initial für (Σ, X, axs) sind, dann sind sie strukturell gleich“, d. h. es existiert eine strukturerhaltende ” Bijektion zwischen den beiden Algebren. Die Menge der initialen Algebren zu (Σ, X, axs) (alle strukturell gleich) heißt der durch (Σ, X, axs) spezifierte abstrakte Datentyp. D. h.: Alle initialen Algebren für (Σ, X, axs) sehen praktisch gleich aus, nämlich so wie A∗Σ. ADT FG KTuEA, TU Ilmenau FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 52 Beispiel: Spezifikation bool. bool vars axs ( abstract data type“). ” Die durch eine (beliebige) initiale Σ-Algebra gegebene Semantik ist die durch die Axiome gegebene. LS – 29.06.+13.07.2010 53 Beispiel: Spezifikation nat. nat sorts ops p, q : bool (Variable der Sorte bool ) ite(true, p, q) = p ite(false, p, q) = q neg(p) = ite(p, false, true) and (p, q) = ite(p, q, false) or (p, q) = ite(p, true, q) nat null : → nat succ : nat → nat Wie sieht die Quotienten-Termalgebra aus? Wie sieht die Standard-Algebra“ aus? ” Was ist der Isomorphismus? Wie sieht die Quotienten-Termalgebra aus? Wie sieht die Standard-Algebra“ aus? ” Was ist der Isomorphismus? FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 54 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 55 Beispiel: Spezifikation natstack. natstacks nat1 + sorts ops axs Beispiel: Spezifikation natqueue. natqueues nat1 + vars axs stack new : → stack push : stack × nat → stack pop : stack → stack top : stack → nat isempty : stack → bool pop(push(s, n)) = s top(push(s, n)) = n pop(new ) = new top(new ) = null Wie sieht die Quotienten-Termalgebra aus? Wie sieht die Standard-Algebra“ aus? ” Was ist der Isomorphismus? Wie sieht die Quotienten-Termalgebra aus? Wie sieht die Standard-Algebra“ aus? ” Was ist der Isomorphismus? FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 56 Das war’s! Viel Erfolg in der Klausur! Schöne Semesterferien! FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 q : queue; n : nat deq(new ) = new deq(enq(new , n)) = new deq(enq(enq(q, n), m)) = enq(deq(enq(q, n)), m) first(new ) = null first(enq(new , n)) = n first(enq(enq(q, n), m)) = first(enq(q, n)) 58 FG KTuEA, TU Ilmenau LS – 29.06.+13.07.2010 57