Gut, morgen jetzt hier einen Schnitt.
Wer von ihnen möchte, kann mir das gleich abgeben,
dann schaue ich mal drüber. Versuchen kann ich es gleich,
aber wir machen jetzt mit der Vorlesung erstmal weiter,
da ist mal die Frau mit der Technik,
alles bereit.
Ja. Okay, super
Dann starten wir. Also, letztes Thema sind,
bei den Datentypen und insgesamt auch das letzte Thema, die Binärbäume.
Und so ganz viele Fohlen haben wir da gar nicht.
Es geht wieder mehr darum, dass sie dann damit selbst arbeiten,
aber ein paar einleitende Folien habe ich dann doch.
Kümmern wir uns zunächst um die Definition. Also,
mit welcher Art von Datentypen haben wir uns bisher beschäftigt?
Wir hatten nicht rekursive Datentypen,
das war zum Beispiel das Transport und
wir hatten rekursive Datentypen
Starten wir Listen und, also hier nochmal ein Beispiel, und natürliche Zahl.
Auch nochmal Beispiele. Was diese beiden Datentypen gemeinsam haben,
ja, also ich meine jetzt die beiden rekursiven Datentypen hier,
dass sie, oder auch noch das dazu genommen,
dass sie eben entweder konstant sind,
wie in dem Fall, oder ich sage jetzt mal,
linear anwachsen.
Das heißt, der Konstrukt erzeugt immer ein neues Element,
das wächst nicht
Exponentiell. Natürlich ist es irgendwie schwierig, das zu handeln,
weil das sind sowieso unendlich viele Objekte,
aber der Konstruktor erzeugt immer sozusagen linear neue Objekte.
Und das ist jetzt anders. Jetzt werden wir nämlich
einen Datentyp behandeln, den Sie sicherlich alle gut kennen,
aber den wir jetzt nochmal aus dieser Sicht betrachten wollen.
Gut, also für den Fall, dass doch der ein
oder andere es vielleicht noch nicht kennt, was sind Binerbäume?
Nun, die Nährbäume, hier haben wir ein Beispiel,
Sind eine Struktur, wo wir eine Wurzel haben,
in dem Fall die Sechs, da kommen wir gleich noch zu.
Und dann haben wir binär, also zwei,
jeweils zwei Knoten, die man als Kinder bezeichnet.
In dem Fall hier die drei und sieben,
die aber selbst wieder verbunden, selbst wieder einen Baum darstellen.
Wenn sie sich das Bild andersrum malen, dann haben sie
halt tatsächlich einen Baum. Gut, aber ich bin mir sicher,
alle oder fast alle haben von Binärbäumen schon gehört.
Weiteres Beispiel, es müssen da keine Zahlen sein,
wäre eben die entsprechende Geschichte wieder mit Hausbaum,
Pferd,
Hund und so weiter
So, wir haben also die Wurzel und die Aufspaltung verschiedene
Äste und so einen Baum, der kann auch leer sein.
Genauso wie die leere Liste gibt es auch den leeren Baum.
So, und wie sieht die Definition in Cock aus?
Tafeln runtermachen, dass sie das gut sehen können.
Also, wir haben einen induktiven Datentyp. Den nennen wir Bintry. Und,
weil wir wieder zulassen wollen, das ähnliche,
weil die Listen, wo wir ja,
nachdem wir uns erst auf die natürlichen Zahlen beschränkt hatten,
dann rübergegangen sind und gesagt haben, okay, nee,
wir betrachten das jetzt für jeden beliebigen Typen,
können wir hier auch beliebige Einträge haben.
Heißt, wir haben einen Parameter, der uns angibt,
worüber eigentlich die Einträge in den Baum sein sollen.
Hier natürliche Zahlen, hier Sachen aus dem Datentyp,
den wir, glaube ich, Nomen genannt hatten.
Gut, wie sieht ein Baum aus? Da haben wir einmal das Analogon zur leeren Liste,
nämlich den leeren Baum und den leeren Baum bezeichnen wir als Blatt lief also ein Blatt,
ist immer ein Bintry, und zwar immer im Bintry vom Typen A.
Und wir haben einen zweiten Konstruktor,
den ich in Ermangelung eines anderen guten Namens,
einfach nur Bintry-Konstruktor genannt habe, wie folgt, der sagt,
wenn wir drei Eingaben kriegen, nämlich erstens ein Wert aus A,
also hier zum Beispiel die sechs oder hier das Haus,
und bereits zwei, zwei, Wie Nährbäume über A,
in dem Fall, fliegt hier die Drei,
sondern dieser ganze Baum hier,
sowie Gießer ganze Baum hier.
Dann erhalte ich, da komme ich jetzt kaum,
warum, diesen ganzen Baum.
Genauso kann ich, wenn ich jetzt erstmal erklären will,
warum ist das hier eigentlich ein binärer Baum? Dann sage ich,
naja, hier hast du ein Element aus A,
dann hast du hier einen binären Baum und hier einen binären Baum.
Also sie sehen, ich umkreise hier
gerade nichts
Kommen wir gleich zu. Das heißt, ich umkreise einen Leaf.
Den habe ich nicht aufgezeichnet. Das ist das, was hier jetzt steht.
Also in unserem Beispiel fehlen noch die Leafs. Heißt,
wenn ich das genauer mache, das ist jetzt das rechte Beispiel,
dann steht hier halt nicht nur Hausbaum,
fährt Hund und so weiter, sondern überall dort,
wo nichts steht, steht nochmal ein Leaf.
Also wir enden mit der leeren Liste.
Das schreibt man normalerweise halt nicht auf. Aber wenn ich
das irgendwie abschließen möchte und den leeren Baum zulassen möchte,
und das möchte ich in Analogie zur leeren Liste,
dann können wir das so machen,
indem wir die Leafs und noch dran schreiben.
Gut. Dann wollen wir uns kurz anschauen, wie wir
die Wurzel bestimmen. Also, was ist das Element in
der Wurzel der folgenden Bäume? Das ist ganz einfach.
Das oberste Element hier ist also die Sechs,
in dementsprechend wieder das oberste ist das Haus.
Und jetzt haben wir wieder
ein Problem, Lehrerbaum
Geht halt irgendwie nicht, ne? Das heißt also,
wenn wir wieder so eine Funktion haben wollen,
dann ist das ganz ähnlich wie Head.
Das ist also die Wurzel herauszuziehen, ist das Analogon zu Head
bei Listen. Und dort mussten wir auf Option oder mithilfe
von Option arbeiten, um eine totale Funktion hinzubekommen.
Und das ist jetzt hier genauso. Sie sehen das.
Diffinition Root. Wieder Christian Parameter, also worüber sind unsere
Einträge? Wir kriegen dann einen Binärbaum und wir bilden eben
nicht in A ab,
sondern den Option
Heißt, wenn wir jetzt B als Eingabe kriegen als Baum,
dann matchen wir B. Und wenn es eben ein Leaf ist,
dann bilden wir auf Non ab,
weil wir können keine Wurzel zurückgeben, es geht nicht.
Und wenn wir irgendwas anderes haben, dann ist ja das hier die Wurzel,
das ist der erste Unterbaum, dass sie der zweite,
dann sagen wir Sam, ey.
Also ähnlich wie bei Head können wir also auch hier Funktionen bestimmen,
wenn sie eigentlich nicht total werden,
indem wir den Trick über das Option gehen
Gut, dann möchte ich einmal zeigen,
wie wir noch eine andere Funktion hier definieren können.
Was soll die Funktion tun? Sie soll einen Baum spiegeln,
sehen das hier am Beispiel, das wird hierran gespiegelt,
an dieser nicht einsehbaren Y-Achse, sie sehen der Baum,
geht nach rechts,
das Pferd geht nach links und dieser Hund geht von ganz links nach ganz rechts.
So, wie sieht so
eine Funktion aus
Diesmal benutzen wir eine, hoffentlich tatsächlich, eine, ja, rekursive Definition.
Deswegen schreiben wir Fixpoint. Das ist der Name unseres Theoriens
. Wir wollen spiegeln. Dann sagen wir wieder,
das ist der Parameter, den wir jetzt immer mitschleifen.
Also worüber sind ja Einträge von den Binärbäumen,
die wir betrachten? Und dann haben hier die Binärbäume.
Und hier stünde besser noch ein Struktur-Bs. Klappt trotzdem,
weil ich will nicht darauf eingehen, warum es trotzdem klappt.
Also hier bitte noch ein in Mengenklammern, Struktur-B denken.
Und was wir rausbekommen, ist ein Bintry vom Typen A
natürlich wieder
Gut, und wie funktioniert die Funktion? Naja, das ist eigentlich einfach.
Wir matchen das B, wenn wir den leeren Baum haben,
dann kommt einfach wieder der leere Baum heraus. Machten Sie darauf,
dass wir an der Stelle hier das A einfügen müssten,
müssen, denn Leave könnte jetzt erstmal,
also während dieses Leave hier an den Typen,
an diesen Parameter gebunden ist,
ist das hier bei diesem Leave erstmal nicht der Fall.
Wir können hier erstmal irgendwas hinschreiben und dann prüft Cock,
hat das tatsächlich den richtigen Typ.
Ja, und wenn wir einfach liefen schreiben,
dann sagt er,
ja lief von Basteln
Da lief es noch nicht eindeutig, sondern wir müssen ihm immer sagen,
okay, der leere Baum, über welchem Typen.
Deswegen lief von A an der Stelle. So,
und wenn wir einen Baum haben, der sich zusammensetzt,
ist es im Grunde ganz einfach. Wir sagen,
dass wir die gleiche Wurzel nehmen und nun nehmen wir zunächst
den rechten Baum, den wir allerdings auch erst widerspiegeln.
Hier. Und unser neuer rechter Baum ist der alte
linke Baum, der aber auch wieder gespiegelt.
Und weil hier eben das Mirror wieder vorkommt,
Haben wir eine rekursive Definition, die akzeptiert wird,
weil sowohl B2 als auch B1 von der Struktur her einfacher sind als das B?
Gut, und dann schauen wir uns mal ein.
Theorem an. Also hier ist die Definition,
die Definition von der Wurzelfunktion und die Definition von der Spiegelfunktion
Und wir beweisen jetzt diese Aussage, die hier steht.
Sie gucken am besten wieder. Ich mache das. Ja
, Sie gucken am besten hier oben rechts. Also,
wir wollen zeigen für alle Typen,
für alle Binärbäume über diesem Typen, gilt,
dass die Wurzel unverändert bleibt, nachdem der ganze Baum gespiegelt wurde.
So, wie zeigen wir das? Zunächst einmal,
wir haben keine Struktur bei diesen beliebigen Typen. Das heißt,
wir machen einfach proof all und sagen, sei das beliebig,
aber fest und für dieses feste A zeigen wir dann
den Rest der Aussage
Gut, wenn wir jetzt folgendes täten,
nämlich zu sagen Proof All, dann hätten wir ein Problem,
weil wir hier dieses Mirror RB irgendwie benutzen müssen und wir
das nicht weiter irgendwie ausixen können,
weil Mirror wiederum rekursiv definiert ist.
Heißt, wir machen hier einfach ein Proof by Induction
und haben dann zwei Dinge zu zeigen. Einmal,
dass die Wurzel Von diesem Leaf gleicht die Wurzel ist von dem gespiegelten Leaf.
So, und jetzt lassen wir ihnen das gescheit ausrechnen und sehen,
er macht uns bei beiden Seiten nann.
Gucken wir uns das nochmal in Ruhe an. Warum?
Nun, Root war hier bei Leaf definiert als Nan.
Okay. Und Mirror von Leaf, was hier steht,
wird zunächst ausgewertet zu Leaf
Und dann haben wir wieder Root A von Leave A.
Und das ist dann, wie wir eben schon gesehen haben
, Nan. Deswegen steht hier Nan gleich Nan.
Und wir können den Beweis abschließen mit Proof Equality.
Gut. Jetzt haben wir die Situation,
dass wir B1 und B2 zwei wie Nährbäume annehmen können,
wo es bereits so ist, dass die Wurzel von B1
die Wurzel von dem gespiegelten Baum von B1 und die Wurzel von B2 gleich
Die Wurzel vom gespiegelten Baum, vom B2 ist.
Und wenn wir uns das jetzt mal überlegen,
inwiefern wir das nutzen können, dann sollte intuitiv klar sein,
dass das für die Wurzel eigentlich gar keine Bedeutung hat.
Also ich kann hier ganz frei sagen,
ich brauche die Geschichten gar nicht.
Machen wir das mal, dann ist ein bisschen mehr Platz.
Denn die werden mit der Wurzel am Ende
nichts zu tun haben.
Wenn ich jetzt was ausrechnen möchte, was wird passieren?
Ich habe hier Root von einem Baum,
der sich zusammensetzt, aus Wurzeln und zwei Teilbäumen.
Und wenn wir uns die Funktion Root angucken an der Stelle,
dann sagt die, völlig egal,
was hinten die beiden Teilbäume sind, gibt zurück,
Sam, ey, also hier wird der Sam A ausrechnen.
Okay, was passiert rechts? Rechts haben wir wieder
die Wurzel, nur jetzt vom gespiegelten Baum.
Und dann müssen wir uns erstmal anschauen,
was macht denn dieser Baum,
wenn der spiegelt
Naja, der macht, lässt das Arvus ist und macht dann
das gespiegelte B2 an diese Stelle und das gespiegelte B1 an diese Stelle.
Und wenn er davon das Root berechnet, dann ignoriert er
diese Spiegelung wieder und konzentriert sich nur auf diese Stelle.
Ich erkläre ihnen das, weil wenn sie das jetzt einfach eintippen,
sehen sie, jo, dann sehen sie, dass sie fertig sind,
ja, aber sie haben vielleicht noch nicht verstanden, warum.
Also deswegen vorher die Überlegung, denn wenn sie einen
handschriftlichen Beweis führen,
müssen diese Überlegungen rein
Okay. Da ist eine Frage, ja klar.
Kommt ja auch die einzelne Schritte in meiner Vereinfachung aus Gruppenwersten?
Ich bin ehrlich gesagt nicht sicher, ob es einen direkten Befehl gibt,
um ihn zu sagen, mach nur einen Schritt.
Das kann schon sein. Was aber auf jeden Fall geht und was ich jetzt auch mache,
wenn ich ordentliche Dateien für mich beispielsweise anlege, ist,
dass ich nach Definition, wie zum Beispiel hier dem Mirror,
ich noch mal kleine Sätze mache,
wo ich ihm das Verhalten von Mirror zum Beispiel auf Leave
sage oder auf den zusammengesetzten Bäumen.
Und dann diese Sätze benutze. Denn die gehen ja
immer dann wirklich nur einen Schritt weit.
Und dann kann man es übersichtlich und nachvollziehbarer gestalten.
Muss man allerdings mehr Sätze für benutzen. Und deswegen,
das ist der Grund, warum ich oder aufstellen,
und das ist der Grund,
warum ich mich dagegen entschieden habe,
weil sie ja keine vollständige Library aufbauen sollen
Aber... Ich spreche ja den vorgehenden Japan. Manchmal auch der Liste. Okay,
da kann ich jetzt nichts zu sagen,
aber das ist auf jeden Fall die Idee,
dass man das, oder eine Möglichkeit,
das tatsächlich auf Schritt für Schritt ausrechnen zu bringen.
Die ich ihnen auch durchaus empfehlen kann,
aber ich kann ihnen nicht verbieten, das simpel zu benutzen.
Nur wenn sie den Übergang dann zu dem Handschriftlichen Beweis haben,
da muss es dann irgendwie auftauchen,
warum das so reduziert.
Gut,
weitere Fragen
Sie merken, ich habe nicht gelogen. Ich habe gesagt,
ich mache nur ganz kurz heute und lasse sie dann
gleich arbeiten und so ist es auch.
Das neue Übungsblatt sollte hochgestellt sein und daran,
also wir gehen jetzt runter und dann können sie
daran arbeiten