40

わかったので、おそらく一生後悔することになると思いますが... ジンは実際にどのように機能しますか?

ドキュメントには、「LJ の拡張」であるアルゴリズムを使用しており、LJT に関する長い紛らわしい論文を示していると書かれています。私が知る限り、これは、どの論理ステートメントが真か偽かを判断するための、高度に形式化されたルールの大きく複雑なシステムです。しかし、これは、型シグネチャを実行可能な式に変換する方法を説明するものではありません。おそらく、すべての複雑な形式的推論が何らかの形で関係しているのでしょうが、全体像は決定的に不完全です。


Pascal インタプリタを BASIC で書こうとしたときと少し似ています。(笑わないでください! 私はまだ 12 歳でした...) 私はそれを理解しようと何時間も費やしましたが、結局あきらめなければなりませんでした。プログラム全体を含む巨大な文字列から、実際に何をすべきかを決定するために、既知のプログラムの断片と比較できるものにどうやって到達するのか、私には理解できませんでした。

もちろん、答えは「パーサー」と呼ばれるものを書く必要があるということです。これが何であり、何をするのかを理解すると、突然すべてが明らかになります。ああ、それをコーディングするのはまだ簡単ではありませんが、アイデアは単純です。実際のコードを書くだけです。12 歳のときにパーサーのことを知っていたら、2 時間も空白の画面を見つめるだけでは済まなかったでしょう。

Djinn が行っていることは基本的に単純だと思いますが、この複雑な論理体操が Haskell ソース コードとどのように関連しているかを説明する重要な詳細が欠けています...

4

3 に答える 3

37

Djinn は定理証明者です。あなたの質問は次のようです: 定理の証明はプログラミングと何の関係がありますか?

厳密に型指定されたプログラミングは、ロジックと非常に密接な関係にあります。特に、ML の伝統における伝統的な関数型言語は、直観主義者の 命題論理と密接に関連しています。

スローガンは「プログラムは証明であり、プログラムが証明する命題はその型である」です。
一般的に考えられるのは

 foo :: Foo

と言うように、それfooは式の証明ですFoo。たとえば、タイプ

 a -> b  

aは からまでの関数に対応するbので、 の証明aと の証明があれa -> bば の証明がありますb。したがって、関数は論理の含意に完全に対応します。同様に

(a,b)

接続詞(論理と)に対応します。したがって、論理トートロジーa -> b -> a & bは Haskell 型に対応し、 a -> b -> (a,b) 次の証明があります。

\a b -> (a,b)

これが「アンド導入ルール」でありながら、「アンド排除ルール」の2つに相当するfst :: (a,b) -> asnd :: (a,b) -> b

同様にa OR b、Haskell 型に対応しEither a bます。

この対応は、 Haskell CurryWilliam Alvin Howardにちなんで「Curry-Howard Isomorphism」または「Curry-Howard Correspondence 」と呼ばれることもあります。

この話は、Haskell の非全体性によって複雑になります。

Djinn は「ただの」定理証明者です。

クローンの作成に興味がある場合は、「Simple Theorem Prover」の Google 検索結果の最初のページに、SML で記述されているように見える LK の定理証明の作成について説明して いる論文があります。

編集:「定理はどのように証明できるのですか?」答えは、ある意味では難しいことではないということです。これは単なる検索の問題です。

次のように言い直した問題を考えてみましょう: S を証明する方法を知っている一連の命題と、P を証明したい命題があります。まず最初に、S における P の証明は既にあるのでしょうか? そうであれば、それを使用できます。そうでない場合は、P でパターン マッチを行うことができます。

case P of
   (a -> b) -> add a to S, and prove b (-> introduction)
   (a ^ b)  -> prove a, then prove b (and introduction)
   (a v b)  -> try to prove a, if that doesn't work prove b (or introduction)

それらのどれも機能しない場合

for each conjunction `a ^ b` in S, add a and b to S (and elimination)
for each disjunction `a v b` in S, try proving `(a -> P) ^ (b -> P)` (or elimination)
for each implication `a -> P` is S, try proving `a` (-> elimination)

本物の定理証明者にはいくらかの頭脳がありますが、考え方は同じです。「意思決定手続き」の研究領域では、機能することが保証されている特定の種類の式の証明を見つけるための戦略を調べます。一方、「タクティクス」では、証明探索を最適に順序付ける方法に注目しています。

について: 「証明を Haskell に変換するにはどうすればよいですか?」

形式システムの各推論規則は単純な Haskell 構造に対応しているため、推論規則のツリーがあれば、対応するプログラムを作成できます。Haskell は結局のところ証明言語です。

含意導入:

\s -> ?

または紹介

Left
Right

そして紹介

\a b -> (a,b)

そして排除

fst
snd

augustss は、彼の回答で、彼が Djinn でこれを実装する方法は、SO の回答には少し面倒だと述べています。ただし、自分で実装する方法を理解できると思います。

于 2012-04-18T22:00:03.763 に答える
24

最も一般的な用語では、Curry-Howard 同型によると、型と命題、および値と証明の間に対応があります。Djinn はこの対応を使用します。

もっと具体的に言って、 type の Haskell 項を見つけたいとしましょう(a, b) -> (b, a)。最初に、型をロジックのステートメントに変換します (Djinn は命題ロジックを使用します。つまり、数量詞は使用しません)。論理ステートメントは次のようになり(A and B) is true implies (B and A) is trueます。次のステップは、これを証明することです。命題論理の場合、ステートメントを機械的に証明または反証することは常に可能です。それを反証できれば、(終了する) Haskell に対応する用語が存在し得ないことを意味します。それを証明できれば、そのタイプの Haskell 項が存在し、さらに Haskell 項は証明とまったく同じ構造を持っています。

最後のステートメントは修飾する必要があります。ステートメントを証明するために使用できるさまざまな公理と推論規則のセットがあります。構成論理を選択した場合、証明と Haskell 用語の間には対応しかありません。「通常」、つまり古典論理にはA or (not A)、公理としてのようなものがあります。これは Haskell 型に対応しますがEither a (a -> Void)、この型の Haskell 用語がないため、古典的なロジックを使用できません。構成命題論理では、どのような命題ステートメントも証明または反証できることは依然として真実ですが、古典論理よりもはるかに複雑です。

つまり、要約すると、Djinn は型をロジックの命題に変換することによって機能し、次に構成的ロジックの決定手順を使用して (可能であれば) 命題を証明し、最後に証明を Haskell 用語に変換します。

(これがどのように機能するかをここで説明するのはあまりにも苦痛ですが、ホワイト ボードの前で 10 分お待ちください。

熟考するための最後のコメントとして、Either a (a -> Void)Scheme を持っている場合は実装できますcall/cc。より具体的なタイプのようなものを選び、Either a (a -> Int)その方法を理解してください。

于 2012-04-19T08:57:26.847 に答える
4

おそらく、私はこれをすべて間違って見ています。おそらく、この形式的な論理はすべて気を散らすものです。LJT などの演繹規則をじっと見つめるのではなく、Haskell を見るべきなのかもしれません。

Haskell には 6 種類の表現があり、何ですか? そして、それぞれが使用する変数に異なる型の制約を課しますよね? そのため、関数の型の引数ごとに 1 つの新しい変数を生成し、どのような式を作成できるかを調べ始めるだけかもしれません。

総当たり検索で可能なすべての式を生成する必要があるわけではありません。どの引数にも関数型がない場合は、関数の適用を試みる意味がありません。すべての引数が多相型変数である場合、case式は役に立ちません。等々。使用可能なタイプは、どの種類の式が機能するかを示します。

コードで既存のトップレベル関数を呼び出せるようにすると、事態はさらに興味深いものになります。ポリモーフィック型に関する面白いスコーピングの問題とは別に、どの関数が役立つか、または役に立たないかを判断するという問題があります。

明らかに、私は離れて、しばらくこのことについて考えなければなりません...

于 2012-04-19T11:15:07.587 に答える