Forschungstage 2025: Beweisen ist auch nur Programmieren (Teil 1)

Wir verwenden JsCoq um Rocq in HTML Webseiten verwenden zu können. Verwendung:

  • Nächstes Kommando ausführen: Pfeil nach Unten klicken bzw. Alt + Down
  • Letztes Kommando rückgängig machen: Pfeil nach Oben klicken bzw. Alt + Up
  • Alle Kommandos bis zur Position des Cursors ausführen: Cursor knopf drücken oder Alt + Enter
Unter Mac sollte Cmd anstatt Alt funktionieren. Folgender Rocq Code initialisiert Rocq für uns und interessiert hier nicht weiter (es kann einer Weile dauern, bis er geladen ist).

Abschnitt 1: Aussagen in Rocq.

Wir beginnen mit einfachen Aussagen in Rocq und Taktiken um mit Aussagen umzugehen.
In Rocq heißen Aussagen Prop und mit (X:Prop) legen wir fest, dass X eine Aussage ist. Wenn X eine Aussage ist, schreiben wir (H:X) um X anzunehmen und diese Annahme bekommt den Namen H.
Mit der Taktik assumption beweisen wir eine Aussage, die wir bereits als Annahme gegeben haben.

Wahrheit

Die Aussage True ist immer wahr und kann mit der Taktik trivial bewiesen werden.

Konjunktion

Wenn X und Y Aussagen sind ist X/\Y die Konjunktion von X und Y. Um eine Konjunktion zu beweisen, müssen beide Teile der Konjunktion bewiesen werden. Die Taktik split teilt eine zu beweisende Konjunktion in ihre beiden Teilaussagen auf und erzeugt für jede ein neues Goal. Mit dem Strich '-' deuten wir an, dass wir eines dieser Goals beweisen.

Wenn wir eine Konjunktion als Annahme haben, zerlegt die Taktik destruct die Konjunktion in ihre beiden Teilaussagen. In den rechteckigen Klammern werden die Namen für die Teilannahmen angegeben.

Gleichheit

Die Aussage x = y besagt dass x und y gleich sind. Die Aussage x = x kann mit der Taktik reflexivity bewiesen werden. Mit (x:nat) legen wir fest, dass x eine natürliche Zahl ist.

Hat man H: x = y als Annahme, ersetzt die Taktik rewrite H alle Vorkommen von x in der zu beweisenden Aussage durch y.

Übungseinheit 1: Aussagen in Rocq

Jetzt seid ihr dran! In dieser Übung sollt ihr euch mit oben vorgestellten Taktiken vertraut machen.

Aufgabe 1.1

Aufgabe 1.2

Aufgabe 1.3

Aufgabe 1.4

Abschnitt 2: Listen in Rocq

In diesem Abschnitt betrachten wir Listen. Zur Einfachheit beschränken wir und auf Listen von natürlichen Zahlen. Wir definieren Listen wie folgt:

Üblicherweise schreibt man nicht cons x xs sondern x :: xs. Folgendes Kommando aktiviert diese Notation in Rocq.

Funktionen über Listen

Wir beginnen mit einfachen Funktionen auf Listen. Mit match implementieren wir eine Fallunterscheidung, ob eine Liste durch nil oder durch cons erzeugt wurde. Im Fall für cons geben die beiden folgenden Namen die Variable für die Zahl und die restliche Liste an. Funktionen können in Rocq auch Aussagen erzeugen. Folgende Funktion erzeugt eine Aussage, die gültig ist, wenn die gegebene Liste nicht leer ist:

Diese Funktion berechnet die Länge einer Liste. Die Funktion inc erhöht eine gegebene Zahl um eins. Das Schlüsselwort Fixpoint ist wichtig um Rocq mitzuteilen dass es sich um eine rekursive Funktion handelt.

Mit eval simpl in können wir in Rocq einen Ausdruck auswerten, z.B. die Länge einer konkreten Liste berechnen:

Die Funktion app hängt eine Liste an eine andere an. Wir benutzen ++ als Notation für diese Funktion.

In Rocq können wir Ausdrücke teilweise auswerten, wenn nicht alle Parameter einer Funktion bekannt sind. Mit Section und Variable können wir festlegen, dass xs eine Variable ist.

Übungseinheit 2: Definieren von Funktionen über Listen

Aufgabe 2.1

Definiert eine Funktion map, die eine Funktion f: nat -> nat auf die Elemente einer Liste anwendet.

Beweisen mit Listen

Bisher haben wir nur Funktionen auf Listen definiert. Nun wollen wir Eigenschaften dieser Funktionen beweisen. Wir haben bereits gesehen dass nil ++ xs zu xs evaluiert. Allerdings evaluiert xs ++ nil nicht zu xs, da xs nicht bekannt ist. Um zu beweisen dass xs ++ nil = xs benötigen wir strukturelle Induktion.
Die Taktik induction xs as [|x xs'] führt eine Induktion über die Liste xs aus. In den eckigen Klammern werden die Namen angegeben. Im Fall für nil müssen keine Variablen vergeben werden, im Fall für cons wird die Zahl x und die restliche Liste xs' genannt. Die Induktionshypothese bekommt den Namen IHxs'. Mit der Taktik simpl wird ein Ausdruck vereinfacht. Das ist ähnlich zu der Evaluierung mit Eval.

Übungseinheit: Strukturelle Induktion

Aufgabe 3.1

Beweist, dass |xs ++ ys| = |xs| + |ys|.

Aufgabe 3.2

Beweist, dass map mit app verträglich ist:



JsCoq's homepage is at github https://github.com/jscoq/jscoq ¡Salut!