提案(P -> Q) -> Q
およびP \/ Q
は同等です。
Haskellでこの同等性を確認する方法はありますか。
from :: Either a b -> ((a -> b) -> b)
from x = case x of
Left a -> \f -> f a
Right b -> \f -> b
to :: ((a -> b) -> b) -> Either a b
to = ???
そのような
from . to = id
およびto . from = id
?
命題_
(P -> Q) -> Q
_と_P \/ Q
_は同等です。
これは、古典的論理には当てはまりますが、構成的論理には当てはまりません。
建設的な論理では 除外された中間の法則 がありません。つまり、「Pが真であるか、Pが真でないかのどちらかで」始めることはできません。
古典的には次のように推論します。
x :: P
_)がある場合)、_Left x
_を返します。nx :: P -> Void
_関数を使用できます。次に、_absurd . nx :: P -> Q
_(すべての型をピークにすることができます。Q
)を取得し、_absurd . nx
_で指定されたf :: (P -> Q) -> Q)
を呼び出して、型Q
の値を取得します。タイプの一般的な機能がないという問題:
_lem :: forall p. Either p (p -> Void)
_
いくつかの具体的なタイプがあります。 Bool
には人が住んでいるので、
_lemBool :: Either Bool (Bool -> Void)
lemBool = Left True -- arbitrary choice
_
しかし、繰り返しになりますが、一般的にはできません。
いいえ、不可能です。 Q = Void
。
Either P Q
はEither P Void
、P
に同型です。
iso :: P -> Either P Void
iso = Left
iso_inv :: Either P Void -> P
iso_inv (Left p) = p
iso_inv (Right q) = absurd q
したがって、関数項がある場合
impossible :: ((P -> Void) -> Void) -> Either P Void
私たちはまた、言葉を持つことができます
impossible2 :: ((P -> Void) -> Void) -> P
impossible2 = iso_inv . impossible
Curry-Howardの対応によると、これは直観主義ロジックのトートロジーになります。
((P -> False) -> False) -> P
しかし、上記は二重否定の排除であり、これは直観主義論理で証明することが不可能であることがよく知られているため、矛盾です。 (classicalロジックで証明できるという事実は関係ありません。)
(最後の注意:これは、Haskellプログラムが終了することを前提としています。もちろん、無限再帰、undefined
、および同様の方法を使用して実際に結果を返さないようにすることで、Haskellの任意の型を使用できます。)
いいえ、それは不可能ですが、少し微妙です。問題は、型変数a
およびb
が普遍的に数量化されていることです。
to :: ((a -> b) -> b) -> Either a b
to f = ...
a
とb
は普遍的に数量化されています。呼び出し元はそれらのタイプを選択するため、どちらのタイプの値も作成できません。これは、引数f
を無視してEither a b
型の値を作成できないことを意味します。しかし、f
を使用することも不可能です。 a
とb
のタイプがわからない場合、f
に渡すタイプa -> b
の値を作成することはできません。タイプが普遍的に定量化されている場合、十分な情報が得られません。
なぜ同型がHaskellで機能しないのか-これらの命題は、建設的な直観主義のロジックで同等であると確信していますか? Haskellは古典的な演繹論理を実装していません。
他の人が指摘したように、私たちは排除された中間の法則を持っていないので、これは不可能です。もう少しはっきりと説明します。私たちが持っていると仮定します
bogus :: ((a -> b) -> b) -> Either a b
b ~ Void
。次に、
-- chi calls this `impossible2`.
double_neg_elim :: ((a -> Void) -> Void) -> a
bouble_neg_elim f = case bogus f of
Left a -> a
Right v -> absurd v
ここで、除外された中間の法則の二重否定特定の命題に適用される場合を証明しましょう。
nnlem :: forall a. (Either a (a -> Void) -> Void) -> Void
nnlem f = not_not_a not_a
where
not_a :: a -> Void
not_a = f . Left
not_not_a :: (a -> Void) -> Void
not_not_a = f . Right
だから今
lem :: Either a (a -> Void)
lem = double_neg_elim nnlem
lem
は明らかに存在できません。a
は、たまたま選択したTuringマシン構成が停止するという命題をエンコードできるためです。
lem
で十分であることを確認しましょう。
bogus :: forall a b. ((a -> b) -> b) -> Either a b
bogus f = case lem @a of
Left a -> Left a
Right na -> Right $ f (absurd . na)
これが論理の観点から有効であるかどうか、またはそれが同等性にとって何を意味するのかはわかりませんが、そうです、そのような関数をHaskellで作成することは可能です。
Either a b
を構築するには、a
またはb
の値が必要です。 a
値を作成する方法はありませんが、呼び出すことができるb
を返す関数はあります。そのためには、a
をb
に変換する関数を提供する必要がありますが、型が不明な場合、定数b
を返す関数を作成できます。そのb
値を取得するために、以前とは異なる方法でそれを構築することはできないため、これは循環推論になり、fixpointを作成するだけで解決できます。
to :: ((a -> b) -> b) -> Either a b
to f = let x = f (\_ -> x) in Right x