$30 off During Our Annual Pro Sale. View Details »

次に流行る※プログラミング言語「Lean」

soukouki
August 20, 2023

 次に流行る※プログラミング言語「Lean」

2023-08-20 Zli OB/OG LT で発表したスライドです。

関数型プログラミング言語であり、定理証明支援系であるLeanについて、かんたんに解説しています。

※ 次に流行ると良いな

soukouki

August 20, 2023
Tweet

More Decks by soukouki

Other Decks in Technology

Transcript

  1. 自己紹介
    misskey: @[email protected]
    twitter: @sou7___
    アンダーバー3つ
    好きな言語: Coq Ruby
    現在学部3年
    4年で卒業できなそうです

    View Slide

  2. プログラミング言語、いくつ書けますか?
    1個
    2-4個
    5個以上(いっぱい)
    ほんのちょっとでも書けたらOK
    2

    View Slide

  3. 好きなプログラミング言語はありますか?
    TypeScript
    Rust
    Haskell
    Ruby
    3

    View Slide

  4. mod_poppoさんのブログ記事
    「これから流行る言語」
    4

    View Slide

  5. 5

    View Slide

  6. 次に流行る※言語「Lean4」の紹介
    Zli OB/OG LT
    2023-08-20
    ※ 流行るといいな
    6

    View Slide

  7. Lean言語のプロ
    フィール
    2013年にマイクロソフトの研究
    所で開発がスタートしました。
    現在は「Lean4」と呼ばれるバ
    ージョンが開発されています。
    前バージョンのLean3からの変
    更の過渡期です。
    検索するときは注意してくださ
    い。
    ロゴかっこいい →
    7

    View Slide

  8. 関数型プログラミング
    HaskellやLispといった、関数型プログラミング言語の仲間です。
    シンプルな関数型言語と違って、オブジェクト指向っぽい機能もあります。
    実質マルチパラダイム言語かもしれないです。
    関数型プログラミングの中でも、純粋関数型と呼ばれるタイプの言語です。
    モ◯◯が出てきますが、◯ナ◯は単に変わった記法くらいに思いましょう。
    ◯◯ドを使うのはそんな難しいことではありません!
    8

    View Slide

  9. はろわ
    def main : IO Unit :=
    let str := "Hello world!"
    IO.println str
    % lean --run hello_world.lean
    Hello world!
    9

    View Slide

  10. Leanの実行方法
    1. オンラインエディタ
    https://lean.math.hhu.de
    2. VSCodeの拡張機能
    めっちゃ高機能!
    3. Lean処理系
    10

    View Slide

  11. 定数(関数)の定義
    -- 定数の定義
    def hello := "Hello"
    -- 関数の定義(関数は第一級オブジェクトなので、定数に関数を代入するイメージ)
    def add1 (n : Nat) : Nat := n + 1
    -- ラムダ式も使えます!
    -- λ {α : Type} (x : α) => x
    def lam := λ {α : Type} (x : α) => x
    11

    View Slide

  12. 条件分岐と入出力
    def main : IO Unit := do
    let stdin ← IO.getStdin
    IO.println "年齢を入力してください"
    let str ← stdin.getLine
    match str.trim.toNat? with
    | none => IO.println "数字を入力してください"
    | some age =>
    if age <= 12 then
    IO.println "こども"
    else
    IO.println "おとな"
    入出力はdo構文というやつを使います。入出力に構文を使うのはPython2も同じです
    し楽勝ですね!
    パターンマッチもあってプログラムも安全!
    12

    View Slide

  13. 代数的データ構造
    inductive Option (α : Type u) where
    | none : Option α
    | some (val : α) : Option α
    みんな大好きOption型。上記の例でも使用してます。
    inductive Bool : Type where
    | false : Bool
    | true : Bool
    Bool(真偽値)型です。trueとTrue、falseとFalseは別物なので注意しましょう。
    inductive Nat where
    | zero : Nat
    | succ (n : Nat) : Nat
    他の言語では見ないNat(自然数)型もあります。 13

    View Slide

  14. 依存型
    pred関数(自然数nから1引いた数を返す)を実装したいとします。
    このとき、引数に0が与えられた場合にどう対応するか困ります。
    14

    View Slide

  15. 普通の言語であれば
    1. 0を返す
    2. 戻り値をOption型にする
    3. 例外/パニックを起こす
    どれもあまり楽しくありません。
    しかし、Leanではもっと楽しい選択肢を取れます!
    15

    View Slide

  16. def pred (n : Nat) : n > 0 → Nat :=
    fun h =>
    match n with
    | Nat.zero => absurd h (Nat.not_lt_zero 0)
    | Nat.succ m => m
    -- checkコマンドは型を表示します。
    #check pred
    -- pred : (n : Nat) → n > 0 → Nat
    n > 0 では、型が値(項)に依存しています。このような型を依存型といいます。
    依存型を持つ言語はLeanの他にCoq、Isabelle、Idrisなどありますが、かなり希少で
    す。
    16

    View Slide

  17. リストからn番目の値を取り出す関数
    このような関数は各言語にありますが、n番目が存在しないときはどのように実装する
    でしょうか。
    1. 戻り値をOption型にする
    2. 引数でデフォルト値を受け取る
    3. 例外/パニックを起こす
    しかしLeanでは「nの範囲を制限する」という手法が使えます。
    補足: 戻り値がOption型のList.get?、引数でデフォルト値を受け取るList.getD、パニックを起こすList.get!というふうに、実
    は全通り用意してあります。
    17

    View Slide

  18. def List.get {α : Type u} : (as : List α) → Fin as.length → α
    | cons a _, ⟨0, _⟩ => a
    | cons _ as, ⟨Nat.succ i, h⟩ => get as ⟨i, Nat.le_of_succ_le_succ h⟩
    Fin as.length は、0以上 as.length 未満の自然数(の集合)です。
    これで、リストからn番目の要素を取ってくる操作を
    例外を使わずに
    必要ないデフォルト値を用意することなく
    Option型を戻り値にすることなく
    実装できます。とても美しい!大好き!
    18

    View Slide

  19. しかし問題が
    長さがnのリストanと、長さがmのリストamがあったとします。
    このとき、 an ++ am (anとamを連結したもの)から値を取り出すには、n+m番目より
    小さい値が必要です。
    標準ライブラリを探すと、List.length_appendという値があり、これを使えばなんと
    かなりそうです。
    でも、これではより複雑になっていったとき、標準ライブラリだけでは解決できませ
    ん。
    つまり、証明が必要になります。
    19

    View Slide

  20. 定理証明支援系 Lean
    カリー・ハワード同型対応によって、以下のような対応があります。
    数学 プログラミング
    命題 型
    証明 プログラム
    場合分け パターンマッチ
    20

    View Slide

  21. 証明の書き方
    証明を書くには、「タクティック」(コマンドみたいなもの)を使います。
    variable {p q : Prop}
    theorem t1 : (p → q) → p → q := by
    intros hpq hp -- (p → q)をhpq、pをhpと名付ける
    apply hpq -- qに対して、(p → q)を適用すると、pになる
    exact hp -- これはhpそのもの
    -- これと対応するプログラム
    theorem t1' : (p → q) → p → q :=
    λ hpq hp => hpq hp
    21

    View Slide

  22. The Natural
    Number Game
    https://www.ma.imperial.ac.uk/~bu
    zzard/xena/natural_number_game/
    自然数の定理をレベル形式で証明す
    るゲームです。
    22

    View Slide

  23. まとめ
    Leanはプログラミング言語であり、定理証明支援系でもある
    そう!君は完璧で究極の言語!
    みんなLeanに入門してみよう!
    23

    View Slide

  24. 参考文献
    「Lean Manual」 https://leanprover.github.io/lean4/doc/
    インストール方法から構文まで書いてある。難易度低め。
    「Functional Programming in Lean」
    https://leanprover.github.io/functional_programming_in_lean/
    より関数型プログラミング言語っぽく書いてある。実践的。
    「Documentation」 https://leanprover-community.github.io/mathlib4_docs/
    標準ライブラリと、数学ライブラリmathlibのリファレンス。
    「Theorem Proving in Lean 4 日本語訳」 https://aconite-
    ac.github.io/theorem_proving_in_lean4_ja/introduction.html
    型理論や証明についてのドキュメント。数少ない日本語資料だけれど、難易度は高
    め。
    24

    View Slide