Gibt es in Anbetracht der Tatsache, dass die Curry-Howard-Korrespondenz so weit verbreitet / erweitert ist, einen Unterschied zwischen Beweisen und Programmen (oder zwischen Aussagen und Typen)? Können wir sie wirklich identifizieren?
Gibt es in Anbetracht der Tatsache, dass die Curry-Howard-Korrespondenz so weit verbreitet / erweitert ist, einen Unterschied zwischen Beweisen und Programmen (oder zwischen Aussagen und Typen)? Können wir sie wirklich identifizieren?
Antworten:
Die Programmiersprachen, die die Leute tagtäglich benutzen, passen nicht so gut in die Curry-Howard-Korrespondenz, weil ihre Typensysteme zu schwach sind. Um mit Curry-Howard etwas Interessantes für imperative Programme zu sagen, muss man ein ausgefeilteres Typensystem haben. Das Buch Adapting Proofs-as-Programs befasst sich mit diesem Aspekt, um imperative Programme zu synthetisieren. Mit zunehmender Beliebtheit abhängiger Typen, insbesondere in Forschungsfunktionssprachen ( Agda , Epigramm ), wird die Unterscheidung immer unschärfer. Natürlich können Sie die Programmsynthese / -extraktion innerhalb des Coq- Theorembeweisers (und vermutlich anderer) durchführen, der natürlich auf Curry-Howard basiert.
Die Curry-Howard-Korrespondenz kann auch in Situationen verwendet werden, in denen die Beweise nicht so eindeutig mit Programmen übereinstimmen (oder es sich nicht um Programme handelt, die jemals jemand ausführen wird). Ein Beispiel hierfür ist die Berechtigung zum Führen von Probeabzügen . Die Aussagen entsprechen Aussagen darüber, wer was darf. Proofs liefern den erforderlichen Nachweis, dass ein Vorschlag gültig ist, sodass eine Autorisierungsanforderung zulässig ist. Zur Kodierung der Proofs werden Proofbegriffe eingeführt (via Curry-Howard). Proof-Terms werden zwischen Parteien als Beweis für die Gültigkeit von Autorisierungsanfragen gesendet, gelten jedoch nicht als Programme.
In Coq gibt es zwei Typen (Prop und Set), die vom Programmierer verwendet werden, um die Beweise, die keinen tatsächlichen Code erzeugen, und den Teil des Beweises, der zum Extrahieren des laufenden Codes (Ihres Programms) verwendet wird, zu trennen.
Das ist eine gute Lösung für das Problem, nach dem Sie fragen, wie Sie feststellen können, was zur Erzeugung von Maschinencode (Programm) gedacht ist und was vorhanden ist, um den Beweis des Satzes (oder Typs) zu vervollständigen.
AFAIK gibt es keine automatische Möglichkeit, beide zu unterscheiden. Das könnte für die Forschung interessant sein? Oder vielleicht kann jemand darauf hinweisen, dass dies eindeutig unmöglich ist?
Bei abhängigen Typen gibt es nicht nur keine klare Unterscheidung zwischen Proofs und Programmen, sondern auch keine Unterscheidung zwischen Programmen und Typen! Die einzige Unterscheidung besteht darin, wo der Typ (oder das Programm) erscheint, wodurch er Teil des "Programm" -Orts oder des "Typ" -Orts eines bestimmten Begriffs ist.
Ein Beispiel wird es klarer machen, hoffe ich:
Wenn Sie die Identitätsfunktion mit abhängigen Typen verwenden, müssen Sie den Typ übergeben, mit dem Sie die Funktion verwenden möchten! Der Typ wird als Wert in Ihrem "Programm" verwendet!
Untypisierte Lambda-Rechnung:
Mit abhängigen Typen:
id: (A: Set) -> A -> A
Wenn Sie diese Funktion verwenden, würden Sie dies folgendermaßen tun:
id Naturals 1
Beachten Sie, dass der "Typ" (in diesem Fall das Set of Naturals), der als Wert übergeben wird, weggeworfen wird, damit er niemals berechnet wird, aber dennoch im "Programm" -Teil des Begriffs enthalten ist. Das ist es, was auch mit den "Beweis" -Teilen passieren wird. Sie müssen vorhanden sein, damit der Begriff überprüft werden kann, aber während der Berechnung werden sie weggeworfen.
Ich werde hier auf die Sprünge gehen und sagen, dass, wenn Sie bereit sind, ein wenig zu blinzeln, Beweise und Abbruchprogramme identifiziert werden können.
Jedes beendende Programm ist ein Beweis dafür, dass Sie seine Eingabe nehmen und seine Ausgabe erzeugen können. Dies ist eine sehr grundlegende Art des Implikationsnachweises.
Damit diese Implikation aussagekräftiger ist als die Angabe des Offensichtlichen, müssen Sie natürlich nachweisen können, dass das Programm für alle Instanzen von Eingaben funktioniert, die aus einer Klasse mit logischer Bedeutung stammen. (Und so auch für die Ausgabe.)
Aus der anderen Richtung ist jeder Beweis mit endlichen Inferenzschritten ein symbolisches Programm, das Objekte in einem logischen System manipuliert. (Wenn wir uns nicht zu viele Gedanken darüber machen, was die logischen Symbole und Regeln rechnerisch bedeuten.)
Das ist ziemlich simpel, aber ich denke, es legt die Robustheit der Idee nahe. (Auch wenn manche Leute es bestimmt nicht mögen. ;-))
Beweis der Irrelevanz?
Wenn Sie ein Programm schreiben, interessieren Sie sich für die Leistung, den Speicherverbrauch usw.
ZB ist es besser, einen cleveren Sortieralgorithmus anstelle der Blasensortierung zu verwenden, selbst wenn deren Implementierungen dieselben Typen aufweisen (auch in abhängigen Typeinstellungen).
Aber wenn Sie einen Satz beweisen, ist es nur die Existenz eines Beweises, an dem Sie interessiert sind.
Natürlich sind aus ästhetischer Sicht einige Beweise einfacher / schöner / inspirierender / etc (zB Beweise aus dem Buch).
Wenn Sie die Curry-Howard-Korrespondenz akzeptieren, handelt es sich hauptsächlich um eine philosophische Frage. "Sind Beweise und Programme unterschiedlich? Natürlich. Wie? Nun, wir nennen Beweise" Beweise "und wir nennen Programme" Programme "."
Oder, um es weniger flippig auszudrücken: Wenn es einen Isomorphismus zwischen Beweisen und Programmen gibt - was eindeutig zu sein scheint -, stellt sich die Frage, ob es ein Orakel gibt, das die beiden unterscheiden kann. Die Menschen stufen sie (größtenteils) als unterschiedlich ein, so dass es zweifellos ein solches Orakel gibt. Es stellt sich dann die wichtige Frage, ob zwischen ihnen ein bedeutender Unterschied besteht, über den philosophisch diskutiert werden muss. Was ist ein "Beweis"? Es gibt keine formale Definition dessen, was ein Beweis ist. Es ist ein Kunstbegriff, ähnlich wie der Begriff "effektiv berechenbar" in der Church-Turing-These. In dieser Hinsicht hat "Programm" auch keine formale Definition.
Dies sind Wörter der natürlichen Sprache, die verwendet werden, um verschiedene Bereiche der mathematischen Forschung zu kategorisieren. Was Curry und Howard beobachteten, war, dass diese beiden unterschiedlichen Bereiche tatsächlich dasselbe studierten. Es ist wichtig, diese Verbindung zu bemerken, da sie besagt, dass diese verschiedenen Forscher miteinander sprechen sollten. Aber auf einer anderen Ebene bedeutet es, den Unterschied zwischen ihnen zu glauben, wenn man den Zusammenhang bemerkt. Wenn Sie ein Problem angehen, ist es manchmal vorteilhafter, es als Programmierproblem zu betrachten, während es manchmal vorteilhafter ist, es als logisches Problem zu betrachten. Ich denke, dieser Unterschied in der Perspektive ist der wichtige Unterschied zwischen ihnen. Aber ob ein Unterschied in der Perspektive einen Unterschied in der Identität ausmacht, ist eine tiefe philosophische Frage, die zumindest bis zu Freges Anfängen untersucht wurdeÜber Sinn und Bedeutung .