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

私を SKI に連れてって

Susisu
December 11, 2015

私を SKI に連れてって

Lazy K の紹介のつもりが型無しラムダ計算の説明から入ったので長くなりすぎたもの

Susisu

December 11, 2015
Tweet

More Decks by Susisu

Other Decks in Programming

Transcript

  1. ࢲΛ SKI ʹ࿈Εͯͬͯ
    201x年m月d日 第3回 OUCC LT会
    のつもりだったけど長すぎてボツ

    View Slide

  2. ͓લ୭ͬͯਓͷͨΊͷ
    すしす
    Twitter: @susisu2413
    GitHub: susisu

    View Slide

  3. ຊ೔ͷ༧ఆ
    λ計算入門
    SKIコンビネータ入門
    Lazy K の紹介

    View Slide

  4. λܭࢉೖ໳

    View Slide

  5. λܭࢉͱ͸
    "計算"を関数とその適用でモデル化
    したもの
    関数型言語の理論的基盤
    ここでは型無しλ計算を紹介します
    型付きもあるんだよ

    View Slide

  6. λࣜ
    変数 a, b, c, ..., x, y, z, ...
    λ抽象 λx.x, λx.λy.(x y), ...
    関数適用 (f x)

    View Slide

  7. λࣜ
    λx.λy.* は λx y.* と略記する
    関数適用の括弧は曖昧でない場合は
    省略する
    x y = (x y)
    関数適用は左結合
    f x y = ((f x) y)

    View Slide

  8. α-ม׵
    λ抽象の束縛変数名は重要ではない
    例えば λx.x = λy.y
    束縛変数名を別の名前に置き換える
    操作をα-変換と呼ぶ
    α-変換で同じλ式にできるなら等価

    View Slide

  9. β-؆໿
    要はただの関数適用の評価
    λ抽象内部の束縛変数を全て引数で
    置き換える
    例えば (λx.f x) y = f y
    β-簡約で同じλ式にできるなら等価

    View Slide

  10. η-ม׵
    どんな引数に対しても同じ結果にな
    るならば、それらは同じといっても
    いいよね (外延的等価性)
    例えば f = λx.f x
    これらの間の変換をη-変換と呼ぶ
    η-変換で同じλ式にできるなら等価

    View Slide

  11. Quiz
    1. λx.x y = λy.y y ?
    2. (λx.λx.x y) y = λy.y y ?
    3. λx.x =
    (λx y z.x z (y z))
    (λx y.x)
    (λx y.x) ?

    View Slide

  12. Answer
    1. No
    2. No
    3. Yes

    View Slide

  13. λܭࢉ
    λ式と変換・簡約の規則をまとめて
    λ計算と呼ぶ
    λ計算はチューリング完全
    どんな手続き (プログラム) もλ式
    で表現できる

    View Slide

  14. Q. Ͳ͏ܭࢉ͢Δͷ
    入力 x が与えられるとする
    手続きを表すλ式 p をうまく選べば、
    例えば y = p x で出力が得られる
    y を変換・簡約すれば解読できそう

    View Slide

  15. Q. ਺஋ͱ͔Ͳ͏͢Δͷ
    数値がなければ、λ式を使えばいい
    じゃない
    真理値がなければ、λ式を使えば
    リストがなければ、λ式を

    View Slide

  16. Church਺
    λ式で自然数を表わすひとつの方法

    View Slide

  17. Church਺
    0 := λf x.x
    1 := λf x.f x
    2 := λf x.f (f x)
    ...

    View Slide

  18. Church਺
    次の自然数を求める関数 Succ
    Succ := λn f x.f (n f x)
    足し算 Add
    Add := λa b f x.a f (b f x)
    掛け算はどうなるか考えてみよう

    View Slide

  19. Church਺
    掛け算 Mul
    Mul := λa b f x.a (b f) x

    View Slide

  20. Church਺
    前の自然数を求める関数 Pred
    Pred := λn f x.
    n (λg h.h (g f))
    (λy.x) (λy.y)
    ただし Pred 0 = 0
    キリがないのでこれ以上はやめる

    View Slide

  21. Churchਅཧ஋
    True := λx y.x
    False := λx y.y
    If := λp x y.p x y = λp.p

    View Slide

  22. Churchਅཧ஋
    AND, OR, NOT
    And := λp q.p q False
    Or := λp q.p True q
    Not := λp.p False True

    View Slide

  23. ड़ޠͷྫ
    Church数 n が 0 かどうか調べる
    0 = λf x.x だった
    IsZero := λn.
    n (λx.False) True
    だんだんとプログラムが書ける気が
    してきませんか?

    View Slide

  24. Churchର
    リストや木構造は対 (pair) の連鎖
    で表現できる
    [1, 2, 3] = (1, (2, (3, 空)))
    対をλ式で表現できればいいよね

    View Slide

  25. Churchର
    対をつくる関数 Cons
    Cons := λx y c.c x y
    かんたん!べんり!

    View Slide

  26. Churchର
    対の前後を取り出す関数 Car, Cdr
    Car := λp.p (λx y.x)
    Cdr := λp.p (λx y.y)

    View Slide

  27. Churchର
    空 (リストの終端) は?
    好きなものを使えば良い
    False が一般的っぽい?

    View Slide

  28. Quiz
    入力 x が 2 つのChurch数 a, b の
    Church対で与えられる
    出力 y = p x が、a = 0 なら y = b、
    それ以外なら y = a * b となる p
    を書いてみよう
    Succ などこれまでに定義したものは
    使ってもよい

    View Slide

  29. Answer
    例: λx.IsZero (Car x) (Cdr x)
    (Mul (Car x) (Cdr x))

    View Slide

  30. ܁Γฦ͠ॲཧ
    繰り返し処理を関数で表現したい時
    は、再帰的な関数を書けばいい
    f(0) = 1, f(n) = n * f(n - 1)
    けれどλ計算では"再帰的な定義"が
    できないので、単純には書けない

    View Slide

  31. ؔ਺ͷෆಈ఺
    関数 f に対して、f x = x となる
    ような x を f の不動点と呼ぶ

    View Slide

  32. Fix
    関数 f を引数にとり、その不動点を
    返す関数 Fix が存在したとする
    Fix f = f (Fix f)
    f = λx n.
    IsZero n True (x (Pred n))
    Fix f n は n 回の空ループになる

    View Slide

  33. Fix
    Fix があれば、繰り返し処理を表現
    することが出来る
    このような関数 Fix をなんとかλ式
    だけで表現できないか?

    View Slide

  34. Fix
    できる!
    Fix := λf.(λx.f (x x))
    (λx.f (x x))
    実際に Fix f = f (Fix f) となるか
    確かめてみるとよいです

    View Slide

  35. λܭࢉͷ·ͱΊ
    λ計算は、計算を関数とその適用で
    モデル化したもの
    チューリング完全
    数値も真理値もリストもλ式で表現
    できる
    繰り返し処理だってできちゃう

    View Slide

  36. SKIίϯϏωʔλೖ໳

    View Slide

  37. ίϯϏωʔλܭࢉͱ͸
    !
    高階関数 (コンビネータ) を用いて計算
    を行う
    λ計算と同じく、簡約が存在
    (P x y z ...) = E
    簡約の結果 E は、コンビネータ P の
    定義による

    View Slide

  38. ίϯϏωʔλͷྫ
    B x y z = x (y z)
    C x y z = x z y
    W x y = x y y

    View Slide

  39. ίϯϏωʔλͷྫ
    S x y z = x z (y z)
    K x y = x
    I x = x
    実は I = S K K とも書ける

    View Slide

  40. SKIίϯϏωʔλܭࢉ
    S、K、I の 3 つのコンビネータを、
    "基底"として用いる
    他のコンビネータは S、K、I の組み
    合わせで表現する
    スキーとは関係がない

    View Slide

  41. SKI ͰԿ͕Ͱ͖Δ͔
    SKIコンビネータ計算はチューリング
    完全
    λ抽象と相互に変換することができる
    SKI→λ は自明
    λ→SKI については Wikipedia の
    「コンビネータ論理」のページを
    見るとよいかも

    View Slide

  42. SKI ͰChurch਺
    0 := KI
    1 := I
    2 := S(S(KS)K)I
    ...
    Succ := S(S(KS)K)

    View Slide

  43. SKI ͰChurchਅཧ஋
    True := K
    False := KI
    If := I

    View Slide

  44. SKI ͰChurchର
    Cons := S(S(KS)(S(KK)(S(KS)
    (S(K(SI))K))))(KK)
    笑っちゃうよね

    View Slide

  45. SKI ͰFix (Y)
    Fix よりも、不動点コンビネータ Y
    と呼ぶことが多い (きがする)
    Y := SSK(S(K(SS(S(SSK))))K)

    View Slide

  46. Quiz
    Church数の掛け算、足し算を SKI で
    書いてみよう
    足し算の方が難しくなるはず

    View Slide

  47. Answer
    Mul = S(KS)K
    Add = S(KS)(S(K(S(KS)))
    (S(KK)))

    View Slide

  48. SKI ͷ·ͱΊ
    S, K, I という 3 つのコンビネータ
    と適用だけで計算をする
    チューリング完全
    λ抽象と相互に変換できる
    データも表せるし、繰り返し処理も
    できる

    View Slide

  49. ͩΜͩΜࣗ෼ͷ SKI ྗ͕ͲΕ΄Ͳͷ΋ͷ͔
    ͔֬Ίͨ͘ͳ͖ͬͯ·ͨ͠ΑͶʁ

    View Slide

  50. Lazy K

    View Slide

  51. ͜͜Ζ
    Ն໨ᕸੴ

    View Slide

  52. lਫ਼ਆతʹ޲্৺ͷͳ͍΋ͷ͸അࣛͩz

    View Slide

  53. lਫ਼ਆతʹ޲্৺ͷͳ͍΋ͷ͸അࣛͩz
    Eager K

    View Slide

  54. Lazy K ͱ͸
    SKIコンビネータ計算をベースにした
    言語
    遅延評価、故に Lazy
    対義語: Eager, Strict
    こころの K とは関係がない

    View Slide

  55. ஗ԆධՁ
    結果に必要のない部分を評価 (計算)
    しないための仕組み
    例えば K x y = x の y は必要ない
    ので、評価を省略したい

    View Slide

  56. ஗ԆධՁ
    ほとんどのプログラミング言語では、
    引数は適用の前に評価される
    Lazy K では、引数はそれ自身が関数
    として適用に使われるまで評価が遅延
    される (使わなければ評価されない)
    これによって、Yコンビネータによる
    停止するループや、無限の長さをもつ
    リストが実現できる

    View Slide

  57. ೖྗ
    入力は文字コードをChurch数で表現
    したものの、Church対によるリスト
    で与えられる
    入力の終端はChurch数 256
    256 = SII(SII(S(S(KS)K)I))
    ただし"リストの終端"ではない

    View Slide

  58. ग़ྗ
    入力 X とプログラム P に対して、
    出力は Y = P X
    出力も文字コードをChurch数で表現
    したものの、Church対によるリスト
    出力の終端も 256 以上のChurch数

    View Slide

  59. ه๏
    Lazy K には 4 つの記法がある
    コンビネータ計算 …… S(KI)I
    unlambda …… ``s`kii
    Iota …… * と i だけ
    Jot …… 0 と 1 だけ

    View Slide

  60. ه๏ ͦͷଞ

    空白、改行は無視される
    # の後は改行までコメント
    空ファイルは I

    View Slide

  61. Lazy K ॲཧܥ
    http://esoteric.sange.fi/essie2/
    download/lazy-k.zip
    Windows 用のバイナリ同梱
    GCC でコンパイルするときは
    lazy.cpp にパッチを当てる
    https://gist.github.com/
    susisu/831e06af2ddee14938c8

    View Slide

  62. Lazy K ॲཧܥ
    実行はファイルから、または -e で
    直接プログラムを指定
    $ lazy
    $ lazy -e

    View Slide

  63. Lazy K ॲཧܥ
    ためしになにか動かしてみる
    $ lazy eg/calc.lazy
    $ lazy -e SKK
    中身を見るともっとたのしい
    SKI を組み合わせて、君だけの最強
    プログラムを作ろう!

    View Slide

  64. Lazy K ͷҋ͸ਂ͍

    View Slide

  65. ࢀߟจݙ
    大体 Wikipedia を読めばいいと思う
    ラムダ計算
    コンビネータ論理
    SKIコンビネータ計算
    不動点コンビネータ

    View Slide

  66. ࢀߟจݙ
    The Lazy K Programming Language
    https://tromp.github.io/cl/lazy-
    k.html
    ↑の日本語訳
    http://legacy.e.tir.jp/wiliki?%CB
    %DD%CC%F5%3A%A5%D7%A5%ED
    %A5%B0%A5%E9%A5%DF
    %A5%F3%A5%B0%B8%C0%B8%ECLazy_K

    View Slide