Lazy K の紹介のつもりが型無しラムダ計算の説明から入ったので長くなりすぎたもの
ࢲΛ SKI ʹ࿈Εͯͬͯ201x年m月d日 第3回 OUCC LT会のつもりだったけど長すぎてボツ
View Slide
͓લ୭ͬͯਓͷͨΊͷすしすTwitter: @susisu2413GitHub: susisu
ຊͷ༧ఆλ計算入門SKIコンビネータ入門Lazy K の紹介
λܭࢉೖ
λܭࢉͱ"計算"を関数とその適用でモデル化したもの関数型言語の理論的基盤ここでは型無しλ計算を紹介します型付きもあるんだよ
λࣜ変数 a, b, c, ..., x, y, z, ...λ抽象 λx.x, λx.λy.(x y), ...関数適用 (f x)
λࣜλx.λy.* は λx y.* と略記する関数適用の括弧は曖昧でない場合は省略するx y = (x y)関数適用は左結合f x y = ((f x) y)
α-มλ抽象の束縛変数名は重要ではない例えば λx.x = λy.y束縛変数名を別の名前に置き換える操作をα-変換と呼ぶα-変換で同じλ式にできるなら等価
β-؆要はただの関数適用の評価λ抽象内部の束縛変数を全て引数で置き換える例えば (λx.f x) y = f yβ-簡約で同じλ式にできるなら等価
η-มどんな引数に対しても同じ結果になるならば、それらは同じといってもいいよね (外延的等価性)例えば f = λx.f xこれらの間の変換をη-変換と呼ぶη-変換で同じλ式にできるなら等価
Quiz1. λ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) ?
Answer1. No2. No3. Yes
λܭࢉλ式と変換・簡約の規則をまとめてλ計算と呼ぶλ計算はチューリング完全どんな手続き (プログラム) もλ式で表現できる
Q. Ͳ͏ܭࢉ͢Δͷ入力 x が与えられるとする手続きを表すλ式 p をうまく選べば、例えば y = p x で出力が得られるy を変換・簡約すれば解読できそう
Q. ͱ͔Ͳ͏͢Δͷ数値がなければ、λ式を使えばいいじゃない真理値がなければ、λ式を使えばリストがなければ、λ式を
Churchλ式で自然数を表わすひとつの方法
Church0 := λf x.x1 := λf x.f x2 := λf x.f (f x)...
Church次の自然数を求める関数 SuccSucc := λn f x.f (n f x)足し算 AddAdd := λa b f x.a f (b f x)掛け算はどうなるか考えてみよう
Church掛け算 MulMul := λa b f x.a (b f) x
Church前の自然数を求める関数 PredPred := λn f x.n (λg h.h (g f))(λy.x) (λy.y)ただし Pred 0 = 0キリがないのでこれ以上はやめる
ChurchਅཧTrue := λx y.xFalse := λx y.yIf := λp x y.p x y = λp.p
ChurchਅཧAND, OR, NOTAnd := λp q.p q FalseOr := λp q.p True qNot := λp.p False True
ड़ޠͷྫChurch数 n が 0 かどうか調べる0 = λf x.x だったIsZero := λn.n (λx.False) Trueだんだんとプログラムが書ける気がしてきませんか?
Churchରリストや木構造は対 (pair) の連鎖で表現できる[1, 2, 3] = (1, (2, (3, 空)))対をλ式で表現できればいいよね
Churchର対をつくる関数 ConsCons := λx y c.c x yかんたん!べんり!
Churchର対の前後を取り出す関数 Car, CdrCar := λp.p (λx y.x)Cdr := λp.p (λx y.y)
Churchର空 (リストの終端) は?好きなものを使えば良いFalse が一般的っぽい?
Quiz入力 x が 2 つのChurch数 a, b のChurch対で与えられる出力 y = p x が、a = 0 なら y = b、それ以外なら y = a * b となる pを書いてみようSucc などこれまでに定義したものは使ってもよい
Answer例: λx.IsZero (Car x) (Cdr x)(Mul (Car x) (Cdr x))
܁Γฦ͠ॲཧ繰り返し処理を関数で表現したい時は、再帰的な関数を書けばいいf(0) = 1, f(n) = n * f(n - 1)けれどλ計算では"再帰的な定義"ができないので、単純には書けない
ؔͷෆಈ関数 f に対して、f x = x となるような x を f の不動点と呼ぶ
Fix関数 f を引数にとり、その不動点を返す関数 Fix が存在したとするFix f = f (Fix f)f = λx n.IsZero n True (x (Pred n))Fix f n は n 回の空ループになる
FixFix があれば、繰り返し処理を表現することが出来るこのような関数 Fix をなんとかλ式だけで表現できないか?
Fixできる!Fix := λf.(λx.f (x x))(λx.f (x x))実際に Fix f = f (Fix f) となるか確かめてみるとよいです
λܭࢉͷ·ͱΊλ計算は、計算を関数とその適用でモデル化したものチューリング完全数値も真理値もリストもλ式で表現できる繰り返し処理だってできちゃう
SKIίϯϏωʔλೖ
ίϯϏωʔλܭࢉͱ!高階関数 (コンビネータ) を用いて計算を行うλ計算と同じく、簡約が存在(P x y z ...) = E簡約の結果 E は、コンビネータ P の定義による
ίϯϏωʔλͷྫB x y z = x (y z)C x y z = x z yW x y = x y y
ίϯϏωʔλͷྫS x y z = x z (y z)K x y = xI x = x実は I = S K K とも書ける
SKIίϯϏωʔλܭࢉS、K、I の 3 つのコンビネータを、"基底"として用いる他のコンビネータは S、K、I の組み合わせで表現するスキーとは関係がない
SKI ͰԿ͕Ͱ͖Δ͔SKIコンビネータ計算はチューリング完全λ抽象と相互に変換することができるSKI→λ は自明λ→SKI については Wikipedia の「コンビネータ論理」のページを見るとよいかも
SKI ͰChurch0 := KI1 := I2 := S(S(KS)K)I...Succ := S(S(KS)K)
SKI ͰChurchਅཧTrue := KFalse := KIIf := I
SKI ͰChurchରCons := S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)笑っちゃうよね
SKI ͰFix (Y)Fix よりも、不動点コンビネータ Yと呼ぶことが多い (きがする)Y := SSK(S(K(SS(S(SSK))))K)
QuizChurch数の掛け算、足し算を SKI で書いてみよう足し算の方が難しくなるはず
AnswerMul = S(KS)KAdd = S(KS)(S(K(S(KS)))(S(KK)))
SKI ͷ·ͱΊS, K, I という 3 つのコンビネータと適用だけで計算をするチューリング完全λ抽象と相互に変換できるデータも表せるし、繰り返し処理もできる
ͩΜͩΜࣗͷ SKI ྗ͕ͲΕ΄Ͳͷͷ͔͔֬Ίͨ͘ͳ͖ͬͯ·ͨ͠ΑͶʁ
Lazy K
͜͜ΖՆᕸੴ
lਫ਼ਆతʹ্৺ͷͳ͍ͷഅࣛͩz
lਫ਼ਆతʹ্৺ͷͳ͍ͷഅࣛͩzEager K
Lazy K ͱSKIコンビネータ計算をベースにした言語遅延評価、故に Lazy対義語: Eager, Strictこころの K とは関係がない
ԆධՁ結果に必要のない部分を評価 (計算)しないための仕組み例えば K x y = x の y は必要ないので、評価を省略したい
ԆධՁほとんどのプログラミング言語では、引数は適用の前に評価されるLazy K では、引数はそれ自身が関数として適用に使われるまで評価が遅延される (使わなければ評価されない)これによって、Yコンビネータによる停止するループや、無限の長さをもつリストが実現できる
ೖྗ入力は文字コードをChurch数で表現したものの、Church対によるリストで与えられる入力の終端はChurch数 256256 = SII(SII(S(S(KS)K)I))ただし"リストの終端"ではない
ग़ྗ入力 X とプログラム P に対して、出力は Y = P X出力も文字コードをChurch数で表現したものの、Church対によるリスト出力の終端も 256 以上のChurch数
ه๏Lazy K には 4 つの記法があるコンビネータ計算 …… S(KI)Iunlambda …… ``s`kiiIota …… * と i だけJot …… 0 と 1 だけ
ه๏ ͦͷଞ空白、改行は無視される# の後は改行までコメント空ファイルは I
Lazy K ॲཧܥhttp://esoteric.sange.fi/essie2/download/lazy-k.zipWindows 用のバイナリ同梱GCC でコンパイルするときはlazy.cpp にパッチを当てるhttps://gist.github.com/susisu/831e06af2ddee14938c8
Lazy K ॲཧܥ実行はファイルから、または -e で直接プログラムを指定$ lazy $ lazy -e
Lazy K ॲཧܥためしになにか動かしてみる$ lazy eg/calc.lazy$ lazy -e SKK中身を見るともっとたのしいSKI を組み合わせて、君だけの最強プログラムを作ろう!
Lazy K ͷҋਂ͍
ࢀߟจݙ大体 Wikipedia を読めばいいと思うラムダ計算コンビネータ論理SKIコンビネータ計算不動点コンビネータ
ࢀߟจݙThe Lazy K Programming Languagehttps://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