Diese Frage gefällt mir sehr gut. Ich weiß nicht viel, aber ich habe ein paar Dinge (unterstützt durch den Wikipedia-Artikel , der einige nette Tabellen und dergleichen selbst enthält):
Ich denke, dass Summentypen / Vereinigungstypen ( z. B. data Either a b = Left a | Right b
) einer inklusiven Disjunktion entsprechen. Und obwohl ich Curry-Howard nicht sehr gut kenne, denke ich, dass dies dies demonstriert. Betrachten Sie die folgende Funktion:
andImpliesOr :: (a,b) -> Either a b
andImpliesOr (a,_) = Left a
Wenn ich die Dinge richtig verstehe, sagt der Typ ( a ∧ b ) → ( a ★ b ) und die Definition besagt, dass dies wahr ist, wobei ★ entweder inklusive oder exklusiv ist oder je nachdem, was Either
repräsentiert. Sie haben die Either
Vertretung exklusiv oder, ⊕; jedoch ( a ∧ b ) ↛ ( a ⊕ b ). Zum Beispiel ⊤ ∧ ⊤ ≡ ≡, aber ⊤ ⊕ ⊥ ≡ ≡ und ⊤ ↛ ⊥. Mit anderen Worten, wenn sowohl a als auch b wahr sind, dann ist die Hypothese wahr, aber die Schlussfolgerung ist falsch, und daher muss diese Implikation falsch sein. Es ist jedoch klar, dass ( a ∧ b ) → ( a ∨ b ), da, wenn sowohl a als auch b wahr sind, mindestens eins wahr ist. Wenn diskriminierte Gewerkschaften eine Form der Disjunktion sind, müssen sie die inklusive Variante sein. Ich denke, dies ist ein Beweis, aber ich fühle mich mehr als frei, mich von dieser Vorstellung abzubringen.
In ähnlicher Weise sind Ihre Definitionen für Tautologie und Absurdität als Identitätsfunktion bzw. nicht terminierende Funktionen etwas abweichend. Die wahre Formel wird durch den Einheitentyp dargestellt , der nur ein Element enthält ( data ⊤ = ⊤
häufig geschrieben ()
und / oder Unit
in funktionalen Programmiersprachen). Dies ist sinnvoll: Da dieser Typ garantiert bewohnt ist und es nur einen möglichen Einwohner gibt, muss er wahr sein. Die Identitätsfunktion repräsentiert nur die bestimmte Tautologie, die a → a .
Ihr Kommentar zu nicht terminierenden Funktionen ist, je nachdem, was Sie genau gemeint haben, eher falsch. Curry-Howard funktioniert auf dem Typsystem, aber die Nichtbeendigung wird dort nicht codiert. Laut Wikipedia , mit Nicht-Beendigung zu tun ist ein Thema, das Hinzufügen es inkonsequent Logik erzeugt ( zB kann ich definieren , wrong :: a -> b
durch wrong x = wrong x
, und damit „beweisen“ , dass ein → b für alle a und b ). Wenn Sie das mit „Absurdität“ gemeint haben, dann sind Sie genau richtig. Wenn Sie stattdessen die falsche Aussage gemeint haben, dann möchten Sie stattdessen einen unbewohnten Typ, z. B. etwas, das durch definiert istdata ⊥
- das heißt, ein Datentyp, der nicht konstruiert werden kann. Dies stellt sicher, dass es überhaupt keine Werte hat und daher unbewohnt sein muss, was falsch ist. Ich denke, Sie könnten wahrscheinlich auch verwenden a -> b
, denn wenn wir nicht terminierende Funktionen verbieten, dann ist dies auch unbewohnt, aber ich bin nicht 100% sicher.
Laut Wikipedia werden Axiome auf zwei verschiedene Arten codiert, je nachdem, wie Sie Curry-Howard interpretieren: entweder in den Kombinatoren oder in den Variablen. Ich denke, die Kombinatoransicht bedeutet, dass die primitiven Funktionen, die wir erhalten, die Dinge codieren, die wir standardmäßig sagen können (ähnlich wie modus ponens ein Axiom ist, weil die Funktionsanwendung primitiv ist). Und ich denke, dass die Variablenansicht tatsächlich dasselbe bedeuten kann - Kombinatoren sind schließlich nur globale Variablen, die bestimmte Funktionen sind. Was primitive Typen betrifft: Wenn ich richtig darüber nachdenke, dann denke ich, dass primitive Typen die Entitäten sind - die primitiven Objekte, über die wir Dinge beweisen wollen.
Nach meiner Logik- und Semantikklasse wird die Tatsache, dass ( a ∧ b ) → c ≡ a → ( b → c ) (und auch b → ( a → c )) zumindest in natürlicher Ableitung als Exportäquivalenzgesetz bezeichnet Beweise. Ich habe damals nicht bemerkt, dass es nur Curry war - ich wünschte, ich hätte es getan, denn das ist cool!
Während wir jetzt eine Möglichkeit haben, eine inklusive Disjunktion darzustellen , haben wir keine Möglichkeit, die exklusive Vielfalt darzustellen. Wir sollten in der Lage sein, die Definition der exklusiven Disjunktion zu verwenden, um sie darzustellen: a ⊕ b ≡ ( a ∨ b ) ∧ ¬ ( a ∧ b ). Ich weiß nicht, wie man Negation schreibt, aber ich weiß, dass ¬ p ≡ p → ⊥ und sowohl Implikation als auch Falschheit einfach sind. Wir sollten daher in der Lage sein, eine ausschließliche Disjunktion darzustellen durch:
data ⊥
data Xor a b = Xor (Either a b) ((a,b) -> ⊥)
Dies definiert ⊥
den leeren Typ ohne Werte, was der Falschheit entspricht. Xor
wird dann definiert, um sowohl ( und ) Either
ein a oder ein b ( oder ) als auch eine Funktion ( Implikation ) von (a, b) ( und ) bis zum unteren Typ ( falsch ) zu enthalten. Ich habe jedoch keine Ahnung, was dies bedeutet . ( Bearbeiten 1: Jetzt tue ich das, siehe nächster Absatz!) Da es keine Werte vom Typ gibt (a,b) -> ⊥
(gibt es?), Kann ich nicht verstehen, was dies in einem Programm bedeuten würde. Kennt jemand eine bessere Möglichkeit, über diese oder eine andere Definition nachzudenken? ( Edit 1: Ja, Camccann .)
Edit 1: Dank Camccanns Antwort (insbesondere der Kommentare, die er hinterlassen hat, um mir zu helfen), denke ich, dass ich sehe, was hier los ist. Um einen Wert vom Typ Typ zu Xor a b
erstellen, müssen Sie zwei Dinge angeben. Erstens ein Zeuge für die Existenz eines Elements von entweder a
oder b
als erstes Argument; das heißt, a Left a
oder a Right b
. Und zweitens ein Beweis dafür, dass es keine Elemente beider Arten gibt, a
und b
- mit anderen Worten, ein Beweis, der (a,b)
unbewohnt ist - als zweites Argument. Was bedeutet es, (a,b) -> ⊥
wenn dies (a,b)
unbewohnt ist, wenn Sie eine Funktion nur dann schreiben können, wenn sie unbewohnt ist? Das würde bedeuten, dass ein Teil eines Objekts vom Typ ist(a,b)
konnte nicht gebaut werden; mit anderen Worten, dass mindestens einer und möglicherweise beide von a
und b
auch unbewohnt sind! In diesem Fall könnten Sie, wenn wir über Mustervergleich nachdenken, unmöglich einen Mustervergleich für ein solches Tupel durchführen: Angenommen, das b
ist unbewohnt, was würden wir schreiben, das zum zweiten Teil dieses Tupels passen könnte? Daher können wir keine Musterübereinstimmung damit durchführen, was Ihnen möglicherweise hilft, zu erkennen, warum dies dazu führt, dass es unbewohnt ist. Die einzige Möglichkeit, eine Gesamtfunktion zu haben, die keine Argumente akzeptiert (wie diese muss, da sie (a,b)
unbewohnt ist), besteht darin, dass das Ergebnis auch von unbewohntem Typ ist - wenn wir dies aus einer Musteranpassungsperspektive betrachten, Dies bedeutet, dass es keinen möglichen Körper gibt, obwohl die Funktion keine Fälle hat es könnte beides haben, und so ist alles in Ordnung.
Vieles davon ist, dass ich laut nachdenke / (hoffentlich) Dinge im laufenden Betrieb beweise, aber ich hoffe, dass es nützlich ist. Ich kann den Wikipedia-Artikel nur empfehlen . Ich habe es nicht detailliert durchgelesen, aber die Tabellen sind eine wirklich schöne Zusammenfassung und es ist sehr gründlich.