Upgrade to Pro — share decks privately, control downloads, hide ads and more …

「プログラミング」と「数学」の関係 〜カリー・ハワード同系対応と定理証明支援系Coq〜

soukouki
March 13, 2024
96

「プログラミング」と「数学」の関係 〜カリー・ハワード同系対応と定理証明支援系Coq〜

2024-02-16 Mariconf Zli 合同LT
2024-02-27 TOGATTA Server LT
で行ったLTスライドです

soukouki

March 13, 2024
Tweet

Transcript

  1. 正解 int func() { // ① int *a[3]; // Array<Pointer<Int>>

    // ② int (*b)[3]; // Pointer<Array<Int>> // ③ int (**c)(); // Pointer<Function<Int>> } 5
  2. 「関数」と「ならば」の関係 Floatを受け取ってIntを返す関数 toInt : Float -> Int Intを受け取ってStringを返す関数 toString :

    Int -> String これらを使って、Floatを受け取ってStringを返す関数を作るとしま す。 6
  3. 「関数」 Aを受け取ってBを返す関数 f : A -> B Bを受け取ってCを返す関数 g :

    B -> C 組み合わせることで、Aを受け取ってCを返す関数 g(f(x)) を作れる 「ならば」 AならばB H1 : A -> B BならばC H2 : B -> C 組み合わせることで、AならばC を証明できる 「関数」と「ならば」どこか似ているような気がしませんか? 9
  4. 「構造体」 x座標とy座標を同時に持つ構造体 struct Point { int x; int y; }

    「かつ」 条件Aと条件Bが同時に成り立つ x > 0 かつ y > 0 「同時に持つ」と「同時に成り立つ」も対応しているように見えませ んか? 13
  5. 実は、構造体の拡張である、代数的データ構造と対応しています。 enum Result<T, E> { Ok(T), Err(E), } RustのResult型は、成功した場合の値 Ok(T)

    と、失敗した場合の値 Err(E) のどちらか一方を持ちます。 「どちらか一方を持つ」と「どちらか一方が成り立つ」のように、こ れらも対応しています。 取れる値の集合が各要素の集合の直和になるので、直和型と呼ばれま す。 16
  6. プログラム風に書いた証明 AならばB H1 : A -> B BならばC H2 :

    B -> C H1とH2を使ったAならばC A -> C の証明 fun x => H2(H1(x)) これなら型検査などの「プログラミング」の道具を応用できそうで す! 21
  7. 定理証明支援系Coq プログラム風に証明を書くことで、証明を検証し、正しい証明かどう かを確かめることができます。 A_implies_C = fun (A B C :

    Type) (H1 : A -> B) (H2 : B -> C) => fun (x : A) => H2 (H1 x). AばらばBは H1 : A -> B BならばCは H2 : B -> C それらを使い、 fun (x : A) => H2 (H1 x) とすることで、AならばC を証明しています。 22
  8. Coqによる「かつ」「または」の証明 Theorem and_comm A B: A /\ B -> B

    /\ A. Proof. case. (* 仮定の A/\B を分解して、AとBを得る *) move=> HA HB. split. (* ゴールの B/\A を分解して、AとBを証明する *) - exact HB. - exact HA. Qed. 24
  9. Theorem or_comm A B: A \/ B -> B \/

    A. Proof. (* 仮定の A\/B を分解して、A->B\/A と B->B\/A を証明する *) case. - move=> HA. right. (* ゴールのB\/Aから右辺を選ぶ *) exact HA. - move=> HB. left. (* ゴールのB\/Aから左辺を選ぶ *) exact HB. Qed. 25