Dann würde ich sagen, beginnen wir. Ich begrüße Sie
ganz herzlich zum heutigen Tag. Heute haben wir, nachdem wir gestern,
die erste nicht-trikusive Datenstruktur kennengelernt haben oder eine nicht-trikusive Datenstruktur kennengelernt haben.
Das erste Mal ist mit einer rekursiven Datenstruktur zu tun,
nämlich mit Listen. Und da ist das Programm wie folgt.
Wir wollen uns überlegen, wie man Listen eigentlich definieren kann.
Da ist etwas so ein Endliches drin,
das werden wir sehen
Irgendwie müssen wir das in den Griff bekommen. Dann soll es
wieder darum gehen, wie können wir Funktionen über Listen definieren.
Und dann natürlich, wie können wir Beweise führen.
Diese Sachen tun wir ab hier zumindest erstmal ganz konkret
für Listen über natürlichen Zahlen. Und dann gehen wir nochmal
einen Schritt weiter und werden uns anschauen, wie wir Polymorphilisten händeln.
Also wie schaffen wir es mit Listen umzugehen,
wenn wir vorher nicht wissen,
welcher Art
die Eingaben sein werden
Da dann wieder Definitionen und Funktionen zu bilden, Beweise kommen dann,
wenn ich das richtig erinnere, in den Übungen vor.
Und da ist erstmal die Frage, also fangen jetzt an
und das erste ist, was ist eigentlich eine Liste?
Das hier zum Beispiel soll eine Liste sein. In dem Fall eine Liste,
die besteht aus 0, 7, 2 und 18,
0, das erste Element 18, das letzte Element.
Aber auch das hier ist eine Liste,
bestehend aus den Elementen,
Baum,
Haus und Pferd
Dann haben wir noch den Kandidaten hier. Die Lehreliste,
wo wir eben keine Elemente enthalten, wo keine Elemente enthalten sind.
Und wenn wir uns jetzt die Beispiele angucken, dann ist
die Frage, wie können wir den Listen ordentlich definieren?
Und wir beschränken uns zunächst mal nur über Listen von natürlichen Zahlen,
also nicht Baumhaus fährt oder so, sondern wirklich nur Listen,
wo die einzelnen Stellen durch natürliche Zahlen belegt sind.
Naja, was wäre der erste Ansatz?
Wir fangen einfach mal an,
sie aufzuziehen
Die leere Liste soll eine Liste sein. Und für alle
natürlichen Zahlen soll die Liste mit genau einem Element oder einem Listenelement,
genauer gesagt, N eine Liste sein.
Für alle N-Am aus den natürlichen Zahlen soll die Liste mit
diesen zwei N-M eine Liste sein.
Entsprechend für drei Zahlen und so weiter. Nun wissen Sie
bereits, Das Punkt, Punkt, Punkt, Schlechtes.
Mit Punkt, Punkt, Punkt können wir nicht ordentlich definieren.
Das geht schon in der Mathematik, die handschriftlich betrieben wird, oft nicht gut.
Manchmal wird es ein bisschen gemacht, ein bisschen geschludert,
aber im Normalfall wird es auch dort schon vermieden.
Aber in Kork geht das überhaupt nicht. Also müssen irgendwie,
seien es fest definiert, was genau damit gemeint ist,
eine Innotation kommt das vor. Aber erstmal geht das so
überhaupt nicht und wir müssen irgendwie einen anderen Weg finden.
Und die Frage ist, Wie können wir es schaffen,
eine unendliche Fallunterscheidung zu erfassen?
Denn genau das haben wir hier, ja. Wir haben,
wenn Sie an gestern denken, da hatten wir in verschiedene Fälle.
Hier haben wir einmal den Fall für,
das ist unser erster Fall hier ohne Elemente,
das ist der zweite Fall mit einem Element, dritte Fall,
mit zwei Elementen und so weiter.
Das heißt also, für jedes N haben wir einen unterschiedlichen
Fall und unterschiedlich viele Parameter, um so eine Liste zu generieren.
Und irgendwie müssen wir
es halt anders hinbekommen
Und der Kniff ist, dass auch wenn unser Datentyp in
gewisser Hinsicht unendlich ist, er doch eine endliche Struktur besitzt.
Wir also nicht immer irgendwas konnten, komplett Neues haben,
sondern diese Sachen sich nach und nach von dem Vorjährigen ergeben,
indem man immer noch mal eins quasi dazu tut.
Und dieses Eins-Der-Zutun, das bleibt fest. Also haben wir
immer noch die leere Liste, die brauchen wir irgendwie.
Und jetzt können wir den Rest wie Volk beschreiben,
wenn L eine Liste ist in eine natürliche Zahl,
dann ist auch in gefolgt von allen Elementen aus L wieder eine Liste.
Als rekrusiver Datentyp sieht das dann in Kork wie folgt aus.
Wir sagen, also es ist ein induktiver Datentyp, Listen nut.
Und wir sagen ihm, wir haben einmal Neil,
wer von ihnen hat schon mit Listen zu tun gehabt,
hat damit operiert?
Ja, einige, aber auch nicht alle
Nil ist immer ein Ausdruck für die leere Liste. Kommt,
ich habe erst mal nachgeguckt, von Not in List.
Aber dieser Ausdruck hat sich einfach eingebürgert. Und die
zweite Möglichkeit ist, dass wir so einen Cons haben.
Das steht für Konstruktor. Also man hatte keinen passenden Namen.
Und inzwischen hat sich das Cons eingebürgert. Was uns sagt,
okay, unabhängig vom Namen, der ist gar nicht so wichtig.
Das Wichtige ist, was hier passiert. Wir nehmen eine
natürliche Zahl und jetzt kommt das Entscheidende und bereits eine Liste.
Hier ist die Rekursion
Und bekommen dann wieder eine neue Liste. Und dadurch,
dass die Konstruktoren durch ihre Eingaben bestimmt sind,
das heißt also, wenn ich hier verschiedene Sachen eingebe,
dann kommt auch jeweils was unterschiedliches heraus,
kann ich auf die Art und Weise diesen Gedankengang hier,
ich sage jetzt mal, simulieren.
Und dementsprechend können wir jetzt in Cock ähm,
die Sachen aufschreiben, ich muss jetzt eine Sache dazu sagen.
Ah, nee, er ist noch nicht gleich.
Erstmal können wir Neil Nutsch schreiben für die Lehreliste.
Was soll das hier sein? Consnat 6, Neil Nutt
? Können wir das immer ein bisschen einfacher benennen?
Jo. Mit dem Element. Genau so ist es.
Und was haben wir hier? Was könnte da,
wofür könnte das stehen? Können wir das immer mal
mündlich erklären
Jo. Genau, die sechs kommt vorne hin.
Und hier? Noch einer? Oder eine? Können Sie
es mir erklären? Nein. Jo. Ja, genau
so ist es. Und dementsprechend würden wir andere Sachen lieber schreiben.
Und ich habe ihr jetzt geschrieben, gewünschte Schreibweise.
Also wir wollen eigentlich Lehreliste, Liste mit sechs,
sechs, sag ich gleich noch was zu,
irgendwie verbunden mit dem L und 648 schreiben.
Das erste ist, hier steht in den Folien, immer noch unterstrich nut.
Ich habe das jetzt in Cock doch anders geregelt, dahingehend,
dass die Notation so ist, das kriegen sie hin,
dass ich einen gewissen Scope aufgebaut habe,
List-Nutscope oder so heißt der.
Und dort können sie jetzt einfach die Zeichen ohne dieses unterstrich nut verwenden.
Das macht es ein bisschen angenehmer,
damit noch zu hantieren, dann ist es nochmal
ein bisschen klarer
Das zweite war, ich wollte hierzu noch was sagen,
das ist ein bisschen angelehnt, wenn ich das richtig erinnere,
die Schreibweise, die ich hier gewählt habe,
es gibt da unterschiedliche, so ein bisschen angelehnt an die Prolock-Schreibweise,
wenn ich das richtig erinnere, dann war das nur,
war das so nur mit Lot,
ja, also mit so einem...
Und das Problem war, dass das Zeichnen war hier
fürs Uda reserviert ist und ich das nicht rausgekriegt habe,
dass der das jetzt oder interpretiert.
Deswegen habe ich ein anderes Zeichen genommen,
nehmen wir einfach das und arbeiten damit
Und das ist natürlich, also diese Schreibweise können wir dann im Cock verwenden.
Gut, schauen wir uns jetzt an, wie wir
Funktionen über Listen definieren können. Als erstes eine Funktion,
die an eine gegebene Liste, eine beliebige Zahl hinten anhängt.
Das sieht wie folgt aus. Also, das erste,
was sie feststellen, hier steht auf einmal was anderes.
Feuerstandort Differenition, ja, als wir eine Funktion definiert haben.
Das war auch recht naheliegend, dass es Differenition heißt.
Wenn sie aber eine rekursive Definition machen,
Und wir werden gleich sehen, dass die rekursiv ist,
dann können sie nicht mit Definition arbeiten, zumindest nicht in meiner Version.
Ich weiß nicht, ob sich das inzwischen schon wieder geändert hat, ja.
Aber bis meiner, bei meiner Version geht es noch nicht.
Und da müssen sie ein anderes Wort verwenden,
das sich persönlich nicht so mega glücklich finde,
aber es ist nun mal das Wort,
was Cock bereitstellt und das ist Fixpoint.
Also wenn sie Fixpoint schreiben, dann können sie danach eine Definition,
eine Funktion definieren, so rum, die rekursiv arbeitet.
Und zwar wie folgt. Sie geben dem Ding,
wie sie das kennen,
einen Namen
Und jetzt, ganz wichtig, geben Sie ihm einen Parameter.
Hier in dem Fall L vom Typenlisten Nuts. Die Funktion,
die nachher rauskommt, die Funktion, die nachher rauskommt,
die hat einen Typen, List Nuts, nach Nuts, nach List Nuts.
Also in dem Fall, dass at at end not.
So. Also dieser, was hier Parame,
als Parameter steht, das kommt dann später,
ist dann einfach die erste Eingabe der Funktion, okay?
So, warum müssen wir das denn hier jetzt als Parameter eingeben?
Nun, der Grund ist,
dass wir über dieses L die Rekursion führen werden und er
über den ersten Parameter die Rekursion führt bei Fixpoint.
Das ist so organisiert. Also,
was tut die Funktion
Sie nimmt sich ein N aus Nat,
das Ale ist ja bereits hier in der Hand.
Und sie matcht L. mit. Und zwar eben einmal der Lehrenliste.
Ja, und wenn es mit der Lehrenliste matcht,
dann gibt es eben die Liste mit dem einen End zurück.
Ja, wenn ich nichts habe, dann ist eben jetzt,
wenn ganz am Ende was einfüge, nur dir ist ein Element da.
Und wenn ich eine Liste habe, die sich zusammensetzt,
ja, und das ist jetzt dieses rekursive Matching,
ich habe irgendeine Zahl
Und ich habe danach irgendeine andere Liste. Sie können übrigens
auch elf Strich schreiben, wenn sie das verwirrt,
dieses elf spielt jetzt überschreibt jetzt sozusagen die Funktion von diesem L. Also
wenn ihnen das lieber ist, können sie hier Stich verwenden.
Ich mag das ganz gerne zu sagen,
das Ale ist in diesem Fall von der Form M gefolgt
von L. Aber das ist ihre Wahl.
Also auf jeden Fall, wenn das diese vor mir hat,
dann tun wir folgendes. Wir machen M gefolgt von,
und jetzt machen wir at at end not LN.
Das hier ist der rekursive Aufruf. Warum können wir das hier tun?
Naja, die Liste L ist kürzer als diese Liste.
Und weil diese Liste hier kürzer ist, können wir diese Funktion bereits benutzen.
Denn wir können uns auf einen Basisfall abstützen.
Und wir wenden die Funktion dann eben,
könnten sie jetzt auf jedes N anwenden,
aber wenn sie natürlich auf dieses gleiche N an,
um dann die Liste zu bekommen,
die L nimmt und am Ende noch ranpackt und dann vorne noch dieses M ranzupacken.
Und das ist dann
die Lösung
Und wir enden, weil wir ein Matching hatten,
wie sie das bereits kennen.
Also nochmal, was ist neu? Neu ist erstens,
das Ding heißt Fixpoint, wenn wir es rekursiv machen.
Und wir müssen hier einen Parameter angeben,
können das nicht hier reinschreiben, hinter den Doppelpunkt.
Und das zweite ist, dass wir,
nachdem wir gematcht haben,
hier den rekursiven Funktionsaufruf benutzen können
Schauen wir uns das Ganze mal,
also hier steht jetzt nochmal die Funktion,
schauen wir uns das Ganze nochmal an,
wie es ein bisschen allgemeiner aussieht, also Fixpoint,
Name der Funktion, Tee vom rekursiven Typ,
gegebenenfalls weitere Parameter, oben ist das nicht der Fall gewesen,
da hatten wir nur den einen Parameter,
Typ des Ergebnisses und dann kommt die eigentliche Funktionsbeschreibung,
da kommt irgendwas und dann irgendwann sollte das kommen wie Match Tee,
Wiz und dann Möglichkeit 1,
Möglichkeit 2 und so weiter,
je nachdem wie viele Möglichkeiten wir haben und am Ende
steht ein End
Schauen wir uns das nächste Beispiel an. A pennt,
das kennen Sie wahrscheinlich, das ist, wenn Sie zwei Listen haben,
also hier und hier, eine dritte Liste zu machen,
indem Sie die ersten beiden Listen aneinander fügen.
Und wie lösen wir das? Naja,
über Rekursion in der ersten Komponente, wie Sie sehen,
wir nehmen die zweite als Eingabe ein und matchen jetzt
unser Elf von oben mit der leeren Liste,
wenn ich die leere Liste mit irgendwas verkette,
dann kommt das irgendwas raus
Das zählen Sie hier, das ist dieses Strich. Und wenn Sie eine Liste,
die selbst aus, en, gefolgt von irgendeiner anderen Liste besteht,
mit einer anderen Liste verketten, dann sagen Sie,
okay, nimm erstmal das N und dann fügst du,
und das klappst du zusammen mit,
also klebst du zusammen besser mit allem,
was sich ergibt, wenn du L, Mittelstrich verkettest.
Da L kürzer ist,
können wir es mit L-Strich
schon verketten
Also das ist ein wichtiger Punkt. Wenn hier jetzt irgendwas stünde,
was nicht irgendwie von der Struktur her einfacher wäre,
dann würde das nicht funktionieren. Es funktioniert nur dann,
wenn klar ist, für den Rechner,
dass hier eine tatsächlich einfachere Struktur ist als da vorne beim Aufruf.
Gut, nächstes Beispiel. Everse. Also wir wollen
eine Liste umdrehen. Wie können wir das machen? Wir
haben also wieder eine Liste und wir kriegen eine Liste raus
Und wir machen die Rekursionen über die Liste und wenn es halt die leere Liste ist,
dann habe ich nichts umzudrehen, im Leipzig die leere Liste.
Und wenn ich irgendwas habe, was von der Form ist,
N gefolgt von einer Liste, naja,
dann mache ich at at at end mit dem N,
also das N kommt noch ganz hinten und vorne kommt das
Reverse vom restlichen L,
also vom restlichen Teil der Liste
So, und jetzt kann ich wieder, jetzt geht es
wieder nochmal um die Schreibweise. Wenn ich jetzt immer schreibe,
Pant, 1, 2, 3, 4,
5, 6, das ist irgendwie nicht so schön.
Und stattdessen können wir schreiben,
und da können sie wieder die Unterstriche beim Nut weglassen,
können wir einfach schreiben, 1, 2,
3 plus plus 4, 5, 6, ja.
Und dann kommt eben raus, ein, zwei,
drei, also die Liste mit 1,
2, 3, 4,
5,
Gut. Wie führt man nun Beweise in Cock,
also Beweise über Listen? Ich würde jetzt vollstellen, Induktion.
Und zwar müssen wir diese Fälle, die wir haben,
diese zwei strukturellen Fälle eben auch in unseren Beweisen einbringen.
Der erste Fall, den wir zu beachten haben,
ist also, dass wir eine leere Liste haben und das zweite,
dass wir irgendeine Liste haben, nicht Element,
das ist nicht so günstig,
welches aus einem Element-E und einer Restliste besteht.
Beim Element
Und die Art und Weise, wie sie es dann benutzen
können in Cock, ist wieder mal proof by Induction.
Nur diesmal ist es tatsächlich etwas, was auch der Mathematiker
Induktion nennt. Nicht eigentlich nur eine Fallunterscheidung. So. Zeige
ich Ihnen jetzt, glaube ich, drei Beweise.
Sehen das hier nochmal, wie das hier definiert wird.
Hier kommen diverse Notationen, dass wir die tatsächlich benutzen können,
wie ich das vorhin gesagt habe
Und Sie sehen, dass der hier auch jeweils erkennt, was das für Listen sind.
Und hier haben wir unsere jeweiligen Funktionen, die ich gerade genannt habe.
Die Schreibweise, man kann hier was ausrechnen lassen.
Und dann kommen wir jetzt zum Beweis. Okay,
also wir haben zu beweisen, dass wir alle Listen aus,
also Listen hat, aber ich sage jetzt immer nur Listen,
gilt, dass L Plus,
also L. A Pant mit der leeren Liste,
L. ergibt.
Was sie ist, wie sie sehen, ein Lämmer hier.
Das heißt, wir werden es später brauchen. Gut,
wie kann ich sowas beweisen? Jo. Genau. Meine
fiese Frage, war das nicht der Basisfall?
Muss ich das überhaupt,
war das nicht so definiert
Die richtige Antwort ist, ja, es war nicht so definiert.
Denn wir hatten die Definition, wenn Sie oben gucken bei A Pant,
geführt darüber, dass wir über das L gematched haben,
also über die erste Eingabe.
Das heißt, Lehreliste plus L,
das muss ich nicht beweisen, plus plus L,
ja, das hat er per Definition drin.
Aber das andere muss ich erst mal nachweisen.
Denn es ist nicht in der Definition enthalten.
Gut, Proof
by Induction
So, jetzt haben wir zwei Fälle. Was kann ich jetzt machen?
Jo. Genau. Und zwar kann ich es jetzt deswegen machen,
weil wir vorne die leere Liste steht und leere Liste plus
irgendeine Liste, insbesondere die leere Liste wieder selbst.
Also leere Liste plus L ist immer L. Das hatten wir definiert.
Deswegen können wir es simpel machen und es kommt
die leere Liste raus
Und hier steht es in taktisch jetzt das Gleiche.
Also, dieselben sind auch gleich. Wir können also machen proof,
equality win, ich das eintippen kann. So. Gut,
jetzt haben wir also zu zeigen,
dass das Ganze auch dann gilt, wenn unsere Liste,
die wir haben, zusammengesetzt ist und können dabei benutzen,
das ist auch ganz wichtig,
dass L plus die leere Liste gleich
L ist
Das kennen sie vom, ich habe ja schon mitbekommen,
die meisten von ihnen kennen,
die Beweise über vollständige Induktionen mit den natürlichen Zahlen.
Das ist ja ganz genauso. Das hier ist unsere Induktionshypothese,
deswegen heißt die auch so,
bezüglich L. Deswegen wird dieser Name von Cock generiert.
Also wir können davon ausgehen,
dass L plus die Lehreliste gleich Alice und haben das Gleiche
auch zu zeigen für Listen,
die einen komplizierteren Aufbau besitzen
Ja, was tun wir? Möchte den anderen noch Zeit geben
? Danke. Das müssen auch die anderen... Ja?
Okay, ich mach's mal. Was erwarten Sie denn?
Wusste gar nichts. Da ist nichts mehr zu vereinfachen.
Denn L plus plus leere Liste war nicht definiert in der Funktion.
Wir haben nur leere Liste plus plus
Aber simpel ist schon mal gut. Nur, dass in
IAL ist es nicht richtig. Wir haben hier etwas von
der Struktur, eine zusammengesetzte Liste plus eine Liste.
Und das wiederum war definiert, weil über die erste Komponente
haben wir ja unsere Funktion definiert. Das heißt,
wenn wir jetzt simpel machen, also im Ziel ausrechnen,
dann sehen Sie, passiert etwas, nämlich Dass wir bekommen Ain,
gefolgt von, und hier ist jetzt die Bindung zu beachten,
die, was ich orange markiert habe, gehört zusammen.
Also eng gefolgt von L. angehängt an die leere Liste.
Nein, A, ich sei einfach L plus L,
ihre Liste. Nochmal, warum passiert das?
Weil wir hier oben in unserer Definition von A Pant,
die jeden Fall geregelt haben, wenn sich das L,
wenn diese erste Sache hier, die Form,
eng gefolgt von einer anderen Liste hat.
Das war definiert, rekrusiv. Und genau diesen rekursiven Aufruf
finden Sie jetzt hier wieder. Dass er nämlich das N
rausnimmt und dann dieses Ellie zusammen mit dem L-Strich zusammenpackt.
Das ist genau das, was jetzt hier auch passiert ist,
dass er, sorry,
dass er dieses N quasi vorne rausnimmt und dann dieses L
mit dieser Liste zusammenpackt.
Gut. Und nun
Ja. Ja, use, equality, IHL, schwupp.
Und jetzt haben wir wieder genau dieselben. Die sind also gleich,
proof, equality. Und dann haben wir dieses erste Lämmer bewiesen.
Machen wir mal weiter. Was haben wir jetzt? Wir wollen jetzt zeigen,
dass für alle zwei Listen,
also wenn wir je zwei Listen haben und eine natürliche Zahl,
dass L plus L-Strich und dann eben dieses N angefügt,
das Gleiche ist, wie L plus und dann das,
was rauskommt, wenn ich an L-Strich das N-Anfüge hinten.
Gut,
wie tut man das?
Ja. Ich rufe bei induction.
Wir konzentrieren uns aufs erste Teilziel. So,
und jetzt ist immer so ein bisschen die Kunst schon mal zu gucken,
wie weit muss ich jetzt eigentlich weiterarbeiten,
also sich nicht mehr Aufwand zu machen,
als nötig ist
Hier sehen Sie schon Lehreliste plus 11 Strich, das kann der ausrechnen.
Und Lehreliste plus etwas kann er auch ausrechnen. Wir können
das uns auch einfach mal, an dem wir ihm einfach sagen,
rechne mal alles aus, was du ausrechnen kannst.
Und dann sehen Sie das, dass das schon mal links
und rechts vom gleichen Zeichen das Gleiche steht.
Das heißt, das Einzige ist, wir wissen irgendwie,
dass L Strich und das N vorne in die Voraussetzung bringen,
bevor wir die Gleichheit zeigen können
Das heißt, auch wenn es möglich wäre,
wir müssen hier jetzt nicht proof by induction machen,
sondern können hier auf unser etwas Älteres, bewährtes Proof all zurückgreifen.
Proof by induction ist nicht falsch, es wäre nur umständlich.
Nochmal proof all. Und jetzt haben wir hier die Gleichheit, die wir beweisen können.
So, das war also unser Induktionsanfang. Und Sie sehen,
wir haben jetzt hier eine Induktionshypothese, die uns sagt,
für alle Listen, Strich und irgendwelche Zahlen in Null,
können wir das machen mit diesem konkreten L.
Wir müssen jetzt unsere Aussage zeigen für Listen der Form,
wo wir N vor dem L vorschalten.
So, probieren wir es erstmal, ob wir ohne Induktion auskommen.
Dann machen wir Proof All. Nochmal Proof All.
Haben wir also das L-Strich und das in Null reingeholt.
Und jetzt ist die Frage, Was können wir hier eigentlich damit anfangen?
Wir haben erstmal, dass wir an der Stelle umformen können.
Denn das En zieht da raus beim Ausrechnen und behält L plus L-Strich.
Und hier können wir auch umformen, auch nach der Definition,
weil En gefolgt von L plus etwas im En gefolgt von
und dann L plus dem, was da hinten steht,
ist.
Deswegen erwarten wir diverse Änderungen,
wenn wir jetzt simpel eingeben
Und so ist es auch. So. Und jetzt sehen Sie
, was haben wir? Wir haben hier jeweils Listen,
die fangen mit Anne an. Und dann kommt hier dieser Teil,
also L plus L, Strich und hinten in Null.
Und hier steht 11 plus Strich mit hinten
in Null
So, was kann man jetzt tun?
Jo. Ja, fast. Es wird das,
wenn wir jetzt in der Induktionshypothese noch die passenden hier kanonischen,
genau, Parameter wählen. Also machen Us all 2,
IHL. Und ich fütter IHL mit L-Strich und in,
es ist L-Strich,
ja,
L-Strich und
Und dann wurde ganz richtig gesagt, das,
was jetzt hier rauskommt, diese Gleichung entspricht,
also der linke Teil der Gleichung entspricht genau dem hier.
Heißt, wir können jetzt sagen, use equality, IHL 0. So.
Und wenn wir das tun, dann sollte jetzt auf beiden
Seiten das Gleiche stehen und so ist es auch.
Und wir können den Beweis abschließen mit Proof Equality
So, dann schauen wir uns noch mal eine Sache an.
Was haben wir hier? Wir wollen zeigen,
dass wenn wir zwei verschiedene Listen haben und wir machen Reverse
von L plus L-Strich, dass das das Gleiche ist,
wie L-Strich umzudrehen und danach das umgedrehte L anzufügen.
Vielleicht, falls ihm das nicht klar ist, mache ich
noch mal ganz kurz. Ein Beispiel, wenn wir haben,
1, 2, plus plus 3, 4, 5.
Und wir wollen das umdrehen. Ich mache das hier mal mit Großer.
Naja, das hier ist 1, 2, 3, 4, 5.
Es muss auf jeden Fall rauf, rauskommen. 5,
4, 3, 2, 1. Und jetzt war die Frage,
können wir das noch irgendwie hier anders ausrechnen und die Behauptung,
die wir hier jetzt aufgestellt haben, ist,
dass es Drei, vier, fünf, Reverse plus eins,
zwei, übers ist.
Und dass das jetzt hier richtig ist, das sehen Sie,
wenn wir das ausrechnen, ist das hier nämlich fünf,
vier, drei.
Und das hier ist 2-1,
sodass wenn wir es hier mit Plus verknüpfen,
wir genau das bekommen,
was dort oben auch steht
Aber das ist ja nun ein Beispiel.
Es könnt ihr bei anderen Listen durchaus noch falsch sein.
Also müssen wir beweisen, dass das tatsächlich korrekt ist.
Gut. Also machen wir wieder unser bewährtes.
Was? Traut sich keiner.
Gut, und wir können ihn auch erstmal einfach alles ausrechnen lassen,
was er durch die Definition einsetzen kann.
Dann sehen Sie, dass er hier natürlich diese leere Liste
plus 11 Strich hat er zu L gemacht,
11 Strich meine ich, hat er hinten was geändert.
Ja, er konnte reverse not von leerer Liste,
kann er zu leerer Liste ausrechnen und deswegen steht hier
plus plus
ihre Liste
So, und nun hat er aber nicht ersetzt,
dass hier hinten plus plus leere Liste,
dass er die leere Liste weglassen kann,
weil das eben in der Definition nicht enthalten war,
aber wir haben es bewiesen.
Also, wir haben dieses Appent, Nad Neil Nutt gehabt,
und das holen wir jetzt mal rein, Fact.
Und damit wir die Geschichte ja ausrechnen können,
was müssen wir also tun?
Damit wir
das benutzen können
Jo. Also Auflösung entspende ich eigentlich,
dass die... Ja, ein bisschen konkreter noch?
Also, und das ist merkenfrei, über den müssen wir
mit dem Freude das Mal... Ja, ja,
das ist richtig, dann mache ich das aber lieber davor.
Dann mache ich jetzt hier Proof All.
Okay. Aber es ging jetzt darum, wie kann ich
von diesem Fakt hier die Geschichte umformen.
Was muss ich dafür tun? Use all har, L-Strich
. Machen wir mal.
Use equality
Okay, was ist das Problem? Ja. Erklär mal
das anders, als sie gerade dachten. Also, wie es
hier, sie haben gedacht, das wäre so geklammert.
Reverse not von der Geschichte. So ist es aber nicht
. Funktion, diese Funktion hier steht sozusagen in Klammern,
plus plus die leere Liste. Also,
muss hier an der Stelle nicht, dass er Strich gewählt werden nur,
sondern es muss genommen werden, Reverse, Nuts, L-Strich.
Okay. Wenn Sie das machen, dann kriegen Sie
diese Geschichte hier. Kann man den Kopf nicht sagen,
weil das erste Mal ist weg, was du gemeint hast.
Gute Frage. Ich weiß nicht, ich glaube,
dass das in der Rent and Cork drin ist.
Ich mag mich aber irren. Was man machen könnte,
man könnte herausfinden, Cock arbeitet mit,
ich kann Ihnen das hier oben einmal kurz zeigen,
ohne da in die Tiefe gehen zu wollen.
Kommen wir hier die Notation. Ah, nee, habe
ich es nicht gemacht. Habe ich es unten gemacht.
Arbeitet mit, mit verschiedenen Leveln, die angeben sozusagen,
wie stark etwas bindet oder trennt.
Und wenn Sie das natürlich aufs genau das gleiche Level bringen,
wie diese Funktionsapplikation, müsste auch wieder die Klammern setzen,
wenn Sie nicht sagen,
dass es links oder rechtsassoziativ ist
Aber ja, grundsätzlich gilt eigentlich,
dass da die Funktion, ich finde das nicht schlecht,
wenn man es weiß, dass er diese Funktion,
die ausgeschriebenen Funktionen, dass die am stärksten binden.
Ja. Dann müssten sie und, und,
oder so ihre Notation machen, dass der,
die Bindungsbereiche gleich sind,
Grundsätzlich kann man ja merken,
dass er in der Richtung... Das ist sicherlich eine Geschmackssache,
ich persönlich bin ein großer Freund davon,
möglichst viele Klammern wegzulassen, weil ich sonst unübersichtlich erfinde.
Aber da kann man drüber streiten. Ich weiß nicht,
ob man ihm sonst, man sonst eine Chance hat,
also mal abgesehen davon, dass man die Bindungsstärken anpasst,
wäre mir jetzt nicht klar, wie es gehen könnte.
Aber vielleicht geht's. Also auf jeden Fall muss jetzt hier
das Reverse not strich plus plus leere Liste aufgelöst werden in Reverse Not Strich.
Und jetzt haben wir auf beiden Seiten das Gleiche und können
dieses Unterziel beenden. So, und müssen jetzt die Induktionsbehauptung,
also in den Induktionsschritt zeigen. So,
wir haben jetzt hier die Induktionshypothese mit unserem L,
das können wir jetzt
neu benutzen
Und jetzt müssen wir vielleicht erstmal unser L-Strich hier reinholen ins Trocknen und gucken,
ob wir so mit Proof All bereits die Sache zeigen können,
gegebenenfalls müssen wir vielleicht nochmal eine Induktion über L machen,
überall Strich machen, das sieht man dann.
Also, das erste ist, wir können hier die Sache ausrechnen,
dass es ähnen gefolgt von L plus plus L-Strich.
Und hier wissen wir auch,
dass das L ist gefolgt von
Es müsste jetzt beides ausrechnen. Schauen wir erst mal nochmal
nur auf die linke Seite. Ah ja, und dann fügt er,
dann rechnet er auch gleich aus, das habe ich gerade nicht gesagt.
Er macht also aus diesem N danach L plus L Strich,
macht er zunächst N, danach L plus L Strich.
Dann kann aber noch weiter ausrechnen,
weil wenn er innen alleine vorne hat und ein Reverse,
dann kann er sagen, ah,
das ist doch der hintere Teil umgedreht.
Und dann dieses Element, was ganz vorne ist,
hinten rangepackt. Das ist das, was sie beim Simple
jetzt hier links sehen
Also, we worse, LL-Strich und hinten das N rangepackt.
Schauen wir uns die rechte Seite nochmal in Ruhe an.
Wir haben, dieser erste Teil dürfte sich nicht verändern,
genau so ist es. Es verändert sich nur der zweite Teil,
hier haben wir Reverse,
Not N und dann kommt L und Reverse war so definiert in solchen Fällen,
dass es eben erst L umdreht und dann N hinten anfügt,
das sollte auch Hier jetzt genauso passieren und so ist es auch.
Wie machen wir weiter? Ist gar nicht so einfach,
hier die Übersicht zu behalten. Ja, Vorschlag. Ich denke,
was soll ihr aus nicht sehen,
was man einsetzen muss, aber jetzt wird man mit Sicherheit
IHL mit den richtigen eingesetzten Elementen verwenden können
Du bist all die HHL und das Preis.
Das ist gleich von dir, wie es legt.
Gut, dann machen wir doch mal Folgendes.
Wir wenden das mal an. Hier haben wir L plus L-Strich
Reverse. Das ist hier dieser Teil. Das heißt,
wir wenden das an, erstmal das IAL tatsächlich auf L-Strich
und schauen mal, ob uns das weiterhilft.
Use all IHL mit Strich. Und dann machen wir
Use Equality IHL
So, sie sehen, er hat das jetzt tatsächlich geändert.
Also das ist jetzt hier dieser Teil, den sie hier jetzt sehen.
Und wir haben jetzt hier fast die gleichen Sachen stehen.
Das einzige ist, wir haben noch dieses at at at
at end hier an unterschiedlichen Positionen.
Also was passiert? Überlegen Sie sich das,
bevor wir uns in Formalismen vertiefen, damit sie sehen,
was hier gerade vor sich geht
Hier steht nichts weiter, als dass wir L-Strich umgekehrt plus
L umgekehrt machen und dann ein N hinten dran.
Und hier steht, dass wir L-Strich umgekehrt machen und dann
L, umgekehrt, mit einem N hinten dran machen.
Dieses N hinten dran kommt hier in verschiedenen Positionen vor.
Und da hatten wir vorhin was bewiesen.
Ich muss das mal
So, dass man es so einigermaßen alles sieht. Nämlich,
dass L plus L-Strich und dann das N hinten dran.
Das Gleiche ist, wie L plus L-Strich mit N
hinten dran. Das müssten wir also benutzen können.
Also machen wir Fact mit diesem etwas längeren Lämmer vom Namen
her.
Und jetzt müssen wir die richtigen Sachen einsetzen. Also es
sind zunächst mal drei Dinge, die wir einsetzen werden bei H.
Und wir müssen uns überlegen, was sind die Sachen,
die wir hier haben wollen? Also wir wollen haben,
dass dieses at at end diesem hier entspricht.
Und dass dann das L.0 was hier steht,
das muss das Reverse NATL-Strich sein,
dass er Strich holt,
muss diese Geschichte
hier sein
Und das N-0 muss N sein. So, heißt,
wir müssen jetzt das L-0 zuerst eingeben, das ist Reverse.
Not L-Strich. Dann haben wir das L-Strich Null muss sein
übers... Not L. Und dann haben wir das N-0,
das muss hier das N sein,
und dann schauen wir mal,
ob wir
das richtig gemacht haben
So. Das ist ja so ein bisschen ein Problem,
was sie nicht so haben, wenn sie jetzt für sich arbeiten,
mit ihrer Auflösung an Computer,
weil da mehr drauf passt.
So, wir haben jetzt also den Teil genau getroffen.
Das heißt, wir müssten Hanull benutzen können.
Use Equality Hanull
Und jetzt sieht man sehr schön, dass da tatsächlich dieselben unten stehen.
Und wir können diesen Revise mit Proof Equality abschließen. Also,
sie sehen mehrere Dinge, gerade an diesem Beispiel,
oder an dieser Folge von Beispielen, die ich ihm jetzt gezeigt habe.
Als erstes sehen sie, dass sie gewisse Lämmer manchmal brauchen,
die ihnen irgendwie selbstverständlich erscheinen, die sie aber erst beweisen müssen.
Dann haben sie gesehen, wie sie überhaupt
Dinge über Listen
beweisen können
Und dann haben sie gesehen,
dass das manchmal technisch durchaus ein bisschen schwierig wird und dass man da gucken muss,
was matcht da mit wem, damit man am Ende die Sätze,
die man hat, genau mit den Sachen anwendet,
dass man in die Situation kommt,
die man gerade zu beweisen hat.
Das erfordert sicherlich ein bisschen Übung. So,
das waren die Beispiele. Ja, ich würde vorschlagen,
ich mache die Folien jetzt zu Ende,
mache also ein bisschen länger als eine Stunde
Und dafür haben wir dann nachher eine Übung am Stück,
damit, finde ich, eine kurze Vorlesung nochmal haben,
was sich dann gar nicht lohnt.
Also, dann rede ich jetzt noch über die Polymorphenlisten
zum Schluss. Wir hatten bisher nur Listen übernatürlichen Zahlen.
Und das Ziel zu Beginn war aber auch die Definition von
Listen wie Baumhaus fährt.
Nun,
wie ist das möglich
Das erste ist, wir müssen eine Menge definieren oder
einen Typen, der Baumhaus und Pferd umfasst.
Zum Beispiel folgende. Nomen hier genannt, ja. Sie sehen,
da sind halt auch noch ein paar andere drin.
Ich könnte diese Liste natürlich beliebig größer machen, damit sie möglichst viel umfasst.
Es geht hier nur um darum, das Prinzip zu verstehen.
Also sie müssen irgendwie Typ von etwas sein.
Und dann können wir Listen, Polymorph definieren.
Schauen wir uns das an,
wie das funktioniert
Als erstes sehen Sie hier wieder, die Definition,
dass die Definition inductive heißt und der Typ heißt jetzt halt
Liststadtlisten hat, weil wir einfach allgemein Listen definieren.
Und was jetzt neu ist, ist, dass hier ein
Parameter auftaucht. Also, irgendeinen Typen kriegen wir rein,
zum Beispiel natürliche Zahlen, aber auch Nomen, ganze Zahlen,
Props,
ja,
was auch immer
Irgendeinen Typen können wir hier reinbekommen. Und dann kriegen wir,
definieren wir da jetzt simultan, also gleichzeitig für alle diese Typen,
Listen über diesen Typen. Und wenn wir das tun,
achso, ich sage jetzt erstmal nochmal den Rest,
dass Neil ist halt der erste Konstruktor und der sagt,
okay, die Lehreliste ist immer vom Typen List A.
Und das Cons sagt jetzt,
okay, du kriegst ein Element vom Typen
Du kriegst eine Liste vom Typenlist A und kriegst so eine neue Liste vom Typen A.
Das war ja nicht speziell, nur für die natürlichen Zahlen,
das können wir mit jedem Typen A machen.
Und genau das passiert hier, parametrisiert über das A.
Und auch hier haben wir wieder vereinfachte Schreibweisen,
also leere Liste, die Liste,
die nur N enthält oder nur Baum oder nur Haus oder sowas.
Diese Schreibweise, diese Schreibweise.
Also die, die sie schon kennen
Und jetzt kann man, also eben hatten wir die Funktion A Paint not.
Und jetzt haben wir noch mal eine Funktion, Pent einfach.
Sie sehen, es ist wieder mit dem Fixpoint,
mit diesem Schlüsselwort fängt es an, um eine rekursive Definition zu machen.
Ein paar Unterschiede gibt es jetzt aber. Als erstes müssen
wir einen neuen Parameter einführen, nämlich hier das A,
das uns sagt, worüber die Listen eigentlich gehen sollen,
die wir hier aneinander fügen.
Dann unsere erste Liste, über die wir die Rekursion machen,
Und jetzt kommt hier noch so ein Strukt, ey,
was sagt uns das? Nun, das sagt uns,
dass wir die Rekursion nicht über den ersten Parameter,
wie das der Defaultwert wäre, hier dieses A machen,
weil über Sachen vom Typen Set können wir keine vernünftige Rekursion machen,
sondern wir wollen die Rekursion über L machen.
Und deswegen müssen wir ihm sagen,
mach bitte hier rüber die Rekursion und das wird mit dem
Strukt L in diesen Mengenklammern gemacht.
Dann kriegen wir
eine zweite Eingabe
Ebenfalls eine Liste vom Typen A, und wir geben wieder eine Liste vom Typen A heraus. Gut,
wir kriegen also diese zweite Eingabe, Lamna 11 Strich,
und wir melden nun L, mit Neil,
also wenn wir die Lehrerliste haben in L,
dann soll wieder ein Strich rauskommen,
und wenn wir haben, dass sich das L,
also wenn wir statt dem L ein Kunz A L haben,
dann, oh, das ist hier noch nicht geändert,
sorry, das soll bedeuten,
dass es nochmal eine andere Schreibweise by the way,
es soll jetzt hier bedeuten,
dann kriegen wir die Liste, die mit A anfängt,
und dann gefolgt wird von Appent A-L-L-Strich.
Also die Schreibweise ist geändert. Die sehen Sie dann aber
in Cock, wie sie aktuell ist.
Ja, was das bedeutet, habe ich gerade erklärt.
Also wie gesagt, es geht darum, worüber wird die Rekursion geführt?
Wir haben zwei Parameter, ja, alles gesagt.
Gut, ein zweites Beispiel, wo wir ein Element,
nämlich das erste,
aus einer Liste herausgreifen wollen
Schauen wir uns Beispiele an, also nämlich die Liste 1,
3, 2 habe, dann soll doch bitte die 1 herausgegriffen werden.
In der Liste Hausbaum, möge bitte das Haus herausgegriffen werden.
Autofahrrad, Flugzeug, bitte Auto, auch alles klar.
Und jetzt? Was machen wir bei der Lehrenliste? Das erste Element der leeren Liste rausgreifen,
Wenn wir jetzt nicht Polymorphilisten hätten, sondern Listen übernatt,
dann könnte man sagen, ach komm,
wir definieren einfach, die Funktion heißt dann übrigens Head.
Wir definieren Head von der leeren Liste gleich null oder irgendeine andere natürliche Zahl. Okay,
kann man zwar drüber streiten,
ob es ein guter Stil ist oder nicht,
aber das Entscheidende ist, es geht nicht mehr bei Polymorphenlisten,
denn wir müssen ja unabhängig vom Typen A,
den wir haben, müssten wir irgendein Element aus A angehen.
Und das können wir nicht, weil wir nicht wissen,
fast ein Element von A sein könnte.
A könnte auch der leere Typ sein
Also, das ist ein echtes Problem, das müssen wir irgendwie angehen.
Und das Problem ist, dass, also nochmal anders formuliert,
dass Cork eben nur totale Funktionen akzeptiert.
Also, zu jeder Eingabe muss es eine Ausgabe geben.
Punkt. Alles andere ist nicht zugelassen.
Und die Frage ist, was können wir tun?
Und da gibt es eine Möglichkeit in Cock,
die ich Ihnen noch vorstellen möchte.
Unsere letzte Option als Wortspiel
Wir agieren mit einem Typen, der heißt Option.
Den kann man, der ist vordefiniert, und zwar wie folgt.
Der ist auch Polymorph, also für jeden Typen A,
haben wir einen Typen Option A.
Es ist jeweils ein Typ, der rauskommt. Und es ist
wie folgt definiert, bevorende Konstruktoren. Sam haben wir,
macht, wenn es ein Element aus A bekommt,
etwas vom Typen Option A und Nan ist immer vom Typen
Option A. Schauen wir uns das mal an.
Ein Beispiel, dann wird es,
glaube ich,
Das Ergebnis von Head von 1-3-2 soll sein Sam 1.
Das Ergebnis von Head von Haus Baum soll sein Sam Haus.
Hier entsprechend Sam Auto. Und hier Nan. Also sie fügen sozusagen
einen Typen hinzu, der es ihnen erlaubt zu sagen,
du hast ein Element aus A,
und das ist das folgende,
oder eben die Möglichkeit zu sagen,
du hast keins
Und wenn man dir rein abbildet, hat man wieder totale Funktionen.
Das ist halt der Trick. Gut, die Funktion sieht dann
wie folgt aus. Es ist wieder eine rekursive Funktion,
also Fixpoint, Head. Für die,
also wir müssen jetzt wieder, weil es seine Polymorphe-Geschichte ist,
für die verschiedenen Typen A das machen.
Wir haben dann die Liste,
über die wir strukturell die Rekursion führen und herauskommen
soll etwas vom Typen Option
Und wir tun das, indem wir sagen, okay,
Mitch, A-U-S und jetzt eben leere Liste geht offen an und wenn ich irgendwie habe,
A, und hier, das ist, wie gesagt,
noch die alte Notation, A, gefolgt von L,
dann kriege ich Sam A. Gut.
So, dann sind wir mit der Vorlesung vor heute
durch und wir geben wieder runter, runter, ja,
wir gehen runter, immer noch,
nicht mehr ganz so viel,
aber runter und sie bearbeiten dort
die entsprechenden Übungen