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

証明しながらプログラミング! - タクティックによるCoqプログラミング

証明しながらプログラミング! - タクティックによるCoqプログラミング

2023-05-14 Zli 大LTで発表したスライドです。
Coqには、タクティックによる証明とプログラミングを行き来できる特性があります。その特性を使って、プログラミングをタクティックを使って書いていきます。

soukouki

May 14, 2023
Tweet

More Decks by soukouki

Other Decks in Technology

Transcript

  1. 自己紹介 学部3年 昨日までpixivの人と一緒に RubyKaigi(松本)に行ってました 趣味 ゲーム : Factorio, Simutrans なろう

    : たくさん 鉄道 : 乗り鉄(ライト層) Twitter: @sou7_ _ _ 好きな言語: Coq Ruby 2
  2. 3

  3. プログラミング(Elm) round : Float -> Int toString : Int ->

    String これらの関数を使って、 Float -> String の関数を作るにはどうするか froatToString : Float -> String froatToString x = toString (round x) 5
  4. プログラミングも、数学の証明も、大体一緒!? 1つ目: A -> B 2つ目: B -> C 求めたいものはA

    -> C AをA -> Bを使ってBに変換する BをB -> Cを使ってCに変換する 7
  5. 証明しながらプログラミングしてみよう From mathcomp Require Import ssreflect. Variables A B C

    : Type. Hypothesis HA_to_B : A -> B. (* 仮定A -> B *) Hypothesis HB_to_C : B -> C. (* 仮定B -> C *) HA_to_Bは A型を受け取ってB型を返す関数 であり AならばBという仮定 HB_to_Cも B型を受け取ってC型を返す関数 であり BならばCという仮定 8
  6. 証明っぽく書くとこう Theorem A_to_C : A -> C. move=> HA. (*

    仮定Aを一旦どける *) apply HB_to_C. (* 仮定B -> Cを使う *) apply HA_to_B. (* 仮定A -> Bを使う *) exact HA. (* 仮定Aを使う *) Qed. 余談 : 高校などで習う証明は仮定から積み上げていく前向き推論が多いのですが、Coq では結論を崩して仮定に落としていく後ろ向き推論を使います。 9
  7. 生成されるプログラムはこう A_to_C = fun HA : A => HB_to_C (HA_to_B

    HA) : A -> C 証明していたら、いつの間にかプログラミングできちゃった!?!? 10
  8. プログラミングの条件分岐 max : Int -> Int -> Int max a

    b = if a > b then a else b よく見る感じ! 12
  9. max関数をCoqで証明っぽく書いてみよう Require Import Arith Classical. Definition max (x y :

    nat): nat. Proof. case_eq (y <=? x) => H. (* y <=? x の結果はtrueまたはfalseになるので、それで場合分け *) - apply x. (* trueの場合、xを適用 *) - apply y. (* falseの場合、yを適用 *) Qed. 15
  10. 生成されたプログラム max = fun x y : nat => ((if

    y <=? x as b return ((y <=? x) = b -> nat) then fun _ : (y <=? x) = true => x else fun _ : (y <=? x) = false => y) : (y <=? x) = (y <=? x) -> nat) eq_refl : nat -> nat -> nat 16
  11. ちょっと型エラーが出るので余計なやつを削り・・・ Definition max' := fun x y : nat =>

    if y <=? x as b return ((y <=? x) = b -> nat) (* returnの後のは型が書いてあります *) then fun _ : (y <=? x) = true => x (* trueの場合、xを返す *) else fun _ : (y <=? x) = false => y. (* falseの場合、yを返す *) 実行! Eval compute in max' 3 2 _. (* = 3 : nat *) 17
  12. カリー・ハワード同形対応 プログラミングの世界 数学の世界 型 命題 プログラム 証明 条件分岐 場合分け 関数

    AならばB それぞれ相互に変換できる! 関数プログラミング言語で関数の型を と書くのは、数学の記法と合わせるため 19