Induktive Beweise über rekursive Sorten Definition: (Partiell Korrektheit) Eine Funktion heißt partiell korrekt, wenn sie keine falschen Resultate (im Sinne der Spezifikation) liefert. Bemerkung: Funktionen, die für gewisse Argumente nicht terminieren, sind auch partiell Korrekt Eine partiell Korrekte Funktion, die stets terminiert, heißt total Korrekt. Um partiell Korrekte Funktionen zu zeigen, ist das Prädikat f Im p ( x) f spez ( x) zu zeigen. Verallgemeinerung: Man benötigt eine Technik, um ein Prädikat P über einer Datenstruktur zu zeigen. => strukturelle Induktion. Notwendig: Begriff der freien Algebra (Informell). Die Werte der freien Algebra sind die Ausdrücke, die aus den Konstruktoren gebildet werden Jedem Konstruktor wird eine Funktion zugeordnet, die auf den Werten der Algebra operiert. Sei type t = C0 | C1 of t | C2 of t * t;; ein Datentyp. Dann ist C0 der einzige Ausdruck, der durch einmaliges Anwenden eines Konstruktors entsteht. (Term der „Tiefe 1“). Durch zweimaliges Anwenden entstehen C1(C0); C2(C0,C0); dreimaliges Anwenden: C1(C1(C0))); C1(C2(C0,C0));… usw. Die Vereinigung aller derart Konstruiierbaren Werte bildet die Menge der Werte der freien Algebra: Funktionen der freien Algebra: C0: C1: C2: t tt: t*tt (Konstante) C1(E1) = E2 C2(E1’,E2’) = E3 Strukturelle Induktion: Offenbar werden alle Werte der freien Algebra aus (endlichen) Werten geringerer Tiefe erzeugt. Das Prinzip der strukturellen Induktion lässt sich also auf derartige freie Algebren anwenden. Gegeben sei ein Datentyp t mit den Konstruktoren C0,…,Cn: Dann gilt das Prädikat x t : P ( x) wenn für alle nullstelligen Konstruktoren Ci das Präsikat P(Ci) gilt. (IA) wenn für Konstruktoren Ci vom Typ T1 * … * Tj (j >0) die Gültigkeit von P(Ci(x1,…,xj)) aus der Gültigkeit von P(x1),…, P(xj) folgt. Beispiel: Binärbäume type ’a btree = Leaf of ’a | Node of ‘a btree * ‘a btree; Es soll nun x (T btree) : P( x) gelten. es gilt P(Leaf(a)) es gilt P(Node(t1,t2)), wenn P(t1) P(t 2) gilt. Wir zeigen nun, dass die Funktion let rec reflect tree = match tree with | Leaf(a) -> tree | Node (t1,t2) -> Node(reflect(t2), reflect(t1));; die Bedingung : reflect(reflect(x))=x erfüllt. Beweis : InduktionsAnfang : x= Leaf(a) reflect(reflect(Leaf(a)) reflect ( Leaf (a)) Def Leaf (a); qed Def Induktionsschritt : Es gelte reflect(reflect(ti)) =ti Dann folgt: i Element {1;2} reflect (reflect ( Node(t1, t 2))) reflect (( Node(reflect (t 2), reflect (t1))) Def Node(reflect (reflect (t1), reflect (t 2))) Def Node(t1, t 2);qed I . A. Denotationale Semantik rekursiver Strukturen Problematik: Einfache Ausdrücke let add x y = x+y;; type farbe =Rot | Gelb |… intuitiv klar. schwieriger : let rec add (x,y) = match x with | 0 -> y | x +1 -> add (x,y) +1;; type lifo =Empty | App of int * Lifo;; unverständlich let f x y = f x y;; type t =T of t;; Erläuterung zur Vorgehensweise: Um die Semantik (Bewertung) rekursiver struktren zu definieren, verwenden wir im Weiteren ein iteratives Vorgehen Wir beginnen mit einer vollkommen undefinierten Sturktur. Über iterative Rechenvorschrifften erweitern wir sukzesive den Definitionsbereich und gelangen schließlich zu einer Funktion mit max. Definitionsbereich. Das Element Bottom: Jedes Funktionsresultat soll eine Bedeutung (Sinn) haben Auf der anderen Seite gibt es Funktionen, bei denen nicht entscheidbar ist, ob sie terminieren (d.h. ein sinnvolles Resultat liefern) Folgerung: Wir müssen ein Objekt einführen, das nicht terminierende Funktionsresultate beschreibt => Dieses Objekt ist ein Wert (mit Semantik) wie beispielsweise 1;2;7… Ordnungen über Megnen M u { } = M Bei der Diskrepanz der Semantik rekursiver Strukturen muss die Wertemenge dieser Funktionen, d.h. M u { } diskutiert. D.h. wir benötigen geeignete Ordnung für M , => Definition einer speziellen Ordnung (flache Ordnung): x y x y (sprich: x ist schwächer definiert als y). Zusammen mit Gleichheit bildet „ “ eine partielle oder Halb-Ordnung, denn es gibt nicht vergleichbare Elemente, Beispiel: in sind alle Zahlen nicht miteinander vergleichbar. Flache Ordnung für -2 -1 0 1… Diese Ordnungen lassen sich verallgemeinern auf Tupel und insbesondere Funktionen ( x, y) ( x ', y ') x x ' y y ' f g x M : f ( x) g ( x) Die Ordnung „ “ über Funktion drückt aus, wie „definiert“ eine Funktion ist. n f g h …-2 … -1 3 0 1 => f g; f h g und h können nicht zueinander in Relation gesetzt werden. 1 1 2 … 2