Also versuche ich, mich um Curry-Howard zu kümmern. (Ich habe es mehrmals versucht, es ist einfach nicht gelierend / scheint zu abstrakt). Um etwas Konkretes anzugehen, arbeite ich an einigen Haskell-Tutorials, die von Wikipedia verlinkt sind, insbesondere von Tim Newsham . Es gibt auch eine nützliche Diskussion, wenn Newsham das Tutorial veröffentlicht.
(Aber ich werde die data
Wrapper von Newsham und Piponi ignorieren und über die zugrunde liegenden Typen sprechen.) Wir haben Hilberts Axiomschema (ausgedrückt als S , K- Kombinatoren); wir haben Sätze als Typen; Implikation als Funktionspfeil; und Modus Ponens als Funktionsanwendung:
axK :: p -> q -> p
axK = const
axS :: (p -> q -> r) -> (p -> q) -> p -> r
axS f g x = f x (g x)
modPons = ($); infixl 0 `modPons` -- infix Left, cp ($) is Right
Dann kann ich das Identitätsgesetz ableiten:
ident = axS `modPons` axK `modPons` axK -- (S K K)
-- ident :: p -> p -- inferred
Diese Typen als bloße Typevars zu haben, die lediglich Aussagen entsprechen, scheint eher einfallslos. Kann ich mehr vom Typsystem verwenden, um die Sätze tatsächlich zu konstruieren? Ich denke:
data IsNat n = IsNat !n -- [Note **]
data Z = Z
axNatZ :: IsNat Z
axNatZ = IsNat Z
data S n = S !n
axNatS :: IsNat n -> IsNat (S n)
axNatS (IsNat n) = IsNat (S n)
twoIsNat = axNatS `modPons` (axNatS `modPons` axNatZ)
-- ===> IsNat (S (S Z))
[Anmerkung **] Ich verwende strenge Konstruktoren gemäß dem Diskussionsthread, um die Einführung von _ | _ zu vermeiden .
Wo:
IsNat
ist ein Prädikat: einen Satz aus einem Begriff machen.n
ist eine Variable.S
ist eine Funktion, die aus einer Variablen einen Term macht.Z
ist eine Konstante (niladische Funktion).
Ich habe also eine eingebettete Prädikatenlogik (erster Ordnung) (?)
Ich schätze, dass meine Typen nicht sehr hygienisch sind; Ich könnte leicht einen Typevar-als-Satz mit einem Typevar-als-Begriff verwechseln. Vielleicht sollte ich das Kind
System verwenden, um sie zu trennen. OTOH, meine Axiome müssten spektakulär falsch sein, um zu einer Schlussfolgerung zu gelangen.
Ich habe nicht ausgedrückt:
- universeller Quantifizierer: Es ist implizit für die freien Vars;
- existentielle Quantität: In der Tat könnten Konstanten als skolemisierte Existentiale wirken;
- Gleichheit der Begriffe: Ich habe wiederholte Typevars in Implikationen verwendet;
- Beziehungen: Das scheint zu funktionieren, oder ist es Verwirrung? ...
data PlusNat n m l = PlusNat !n !m !l
axPlusNatZ :: IsNat m -> PlusNat Z m m
axPlusNatZ (IsNat m) = PlusNat Z m m
axPlusNatS :: PlusNat n m l -> PlusNat (S n) m (S l)
axPlusNatS (PlusNat n m l) = PlusNat (S n) m (S l)
plus123 = axPlusNatS `modPons`
(axPlusNatZ `modPons`
(axNatS `modPons` (axNatS `modPons` axNatZ)) )
-- ===> PlusNat (S Z) (S (S Z)) (S (S (S Z)))
Das Schreiben der Axiome ist einfach, mit freundlicher Genehmigung von Wadlers Theorems for Free! . Die Beweise zu schreiben ist harte Arbeit. (Ich werde die modPons
Funktion fallen lassen und nur die Funktionsanwendung verwenden.)
Erreicht dies tatsächlich eine Logik? Oder ist es verrücktes Zeug? Soll ich aufhören, bevor ich meinem Gehirn mehr Schaden zufüge?
Sie sollten abhängige Typen benötigen, um FOPL in Curry-Howard auszudrücken. Aber ich scheine das nicht zu tun (?)
IsNat
dass Sie keinen Satz aus einem Begriff machen, sondern einen Satz aus einem Satz .IsNat
ist nur ein Typ, also muss es ein Vorschlag sein. OK, ebensoIsNat n
ist es nur ein Typ, also muss es ein Satz sein. Ich muss 'auf meiner Ehre' sein, um nichtn
in das Proposition-Land entkommen zu lassen / als Argument für einen logischen Zusammenhang erscheinen zu lassen (weshalb ich über Typhygiene gesprochen habe). Wären Sie glücklicher, wenn ich die Kirchencodierung für Nats verwenden würde? Ich glaube, ich erweitere λ-calc nur mit Konstruktoren aufn
ist ein Satz : es sagt : ‚Ich bin bewohnt‘. Was nicht mehr ist, als jeder Typevar unter CH sagt.IsNat n
sagt / bezeugt: Außerdem ist der Einwohner vonn
einer bestimmten Art, auch bekannt als "Art" in der Logik. Dann gehe ich über einfach eingegebene λ-calc (?)Antworten:
Um zu erklären, warum ich mich mit Newshams und (besonders) Piponis
data
Wrappern unwohl fühle ... (Dies wird mehr eine Frage als eine Antwort sein, aber vielleicht hilft es zu erklären, was mit meinem falsch istIsNat
, obwohl es Newsham sehr ähnlich zu sein scheint. )Piponi Seite 17 hat:
Ich sehe hier keine Typen. Wenn Sie einen Datenkonstruktor buchstabieren,
:->
funktioniert er nicht als Funktionspfeil. Wenn Sie einen DatenkonstruktorMP
(für Modus Ponens) buchstabieren , funktioniert er nicht als Anwendung. Es gibt einen 'intelligenten Konstruktor'-Operator(@@)
fürMP
, der jedoch keine Funktion anwendet: Er führt lediglich einen Mustervergleich für den:->
Konstruktor durch.Newsham hat (ich beginne mit dem Implikationsabschnitt / Modus Ponens):
Das sieht eher so aus: Wir haben Typen, Funktionspfeile, Funktionsanwendungen in
impElim
. Der TypkonstruktorImp
mit seinen Injektions- und Eliminierungsregeln spiegelt die Beweisbaumstrukturen in den Lectures on Curry-Howard-Isomorphismus wider . Aber ich bin nervös: Warum brauchtImp
man einen Typkonstruktor und einen Datenkonstruktor? Auch hier macht die Rechtschreibung as:=>
keinen Funktionspfeil. Warum all dieseProp
Konstruktoren zum Ein- und Auspacken ? Warum nicht einfachProp (p -> q)
?Wenn ich mir also den Abschnitt "Konjunktion" anschaue (der eigentlich an erster Stelle steht):
Diese
Elim
Funktionen verwenden keine Funktionsanwendung. Sie stimmen lediglich mit den Konstruktoren überein. Es gibt keine implizite Struktur für die Konjunktion: Wir verlassen uns ausschließlich darauf, dass der 'Programmierer' nur dieandInj
Regel verwendet hat, um einen Typ zu erstellen(p :/\ q)
.Wenn Newsham zur Kommutativität der Konjunktion kommt:
Und behauptet
Ich bin einfach anderer Meinung:
commuteAnd
hängt von der internen Struktur des:/\
Typkonstruktors ab.andElim
s tun „Peek“ in die Struktur.Ich würde erwarten, dass wir die Kommutativität der Konjunktion anhand ihrer Definition beweisen können, ohne ein Axiom zu benötigen, um dies zu sagen (?)
OK, wenn ich so puristisch bin, was erwarte ich dann? Diese Konjunktion basiert auf der Kodierung der Kirche für Paare:
Jetzt kann ich
commuteAnd
mit der 'richtigen' Funktionsanwendung schreiben :Diese Funktionsdefinition ist dieselbe wie die von Newsham. Aber ich habe die Signatur auskommentiert, weil der abgeleitete Typ von GHC nicht allgemein genug ist. Es will
Prop ((p -> p -> p) -> p) -> ((p -> p -> p) -> p)
. Welches ist nur eine ausgefallene Variation des Identitätsgesetzes.Bearbeiten: (Nach @DerekElkins erstem Kommentar hier.) Verschrotte alles:
Ich brauche einen höherrangigen Typ, aber keinen Impredicative. Und nicht auf den Typ für,
Conj
sondern fürcommuteAnd
OK. Ich kann gerne ad infinitum Argumente austauschen.
[Ende der Bearbeitung]
Meine Frage: Wenn es legitim ist, was Newsham mit Verschachtelungskonstruktoren und Mustervergleich überall macht, was ist dann nicht legitim an meinem
IsNat
und Mustervergleich?quelle
Proposition
undProof
keine Beispiele für die Curry-Howard-Korrespondenz in Aktion. Diese bilden lediglich ein einfaches Proof-System im LCF-Stil. Die Curry-Howard-Korrespondenz wird durch diecompile
Funktion (obwohl der größte Teil der Arbeit von(^)
und erledigt wirdshow
) bestätigt, die dieseProposition
s undProof
s in Haskell-Code umwandelt. Was Newshams Code betrifft, machen die Wrapper(:=>)
im Wesentlichen keinen Unterschied(->)
. Er fügt sie nur hinzu (wie er ausdrücklich angibt), damit er später eine andere, nicht triviale Implementierung austauschen kann.(:=>)
ist implementiert als(->)
. Ein Modell / eine Simulation einer Logik erfordert jedoch eine Validierung des Interpreters (?). Warum kann ich nicht direkt in Haskell ausdrücken(->)
?(^)
, sich mit Klassik zu befassen. OK, ich werde versuchenshow
, Haskell-Code zu generieren und zu sehen, wie sich das unterscheidet. (Ich werde auch versuchen herauszufinden, wie er sich vorstelltInteger
.) Ich versuche, ein Minimum an Haskell-Maschinen zu verwenden, aus Angst, ich werde_|_
irgendwo etwas einführen und "Programme sind Beweise" untergraben.