Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

(Lambdaだけで) 純LISPのような ナニかを作る

1,872 views

Published on

ラムダ式で純LISPに近いものを組み上げます

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

(Lambdaだけで) 純LISPのような ナニかを作る

  1. 1. (Lambdaだけで) 純LISPのような ナニかを作る @maruuusa83 Daichi Teruya Okinawa National Collage of Technology
  2. 2. λ 2 自己紹介 • まるさ(@maruuusa83) • 沖縄高専メディア科5年生
  3. 3. λ 3 自己紹介
  4. 4. λ 4 自己紹介
  5. 5. λ 5 自己紹介
  6. 6. アジェンダ • 自己紹介 • 今回やることとか色々 • 特殊形式の定義 • CONS, CAR, CDR • COND • データ構造の定義 • CONDの定義 • EQ • 値の定義 • EQの定義 λ 6
  7. 7. • かなりいい加減な独自研究に満ちています! • 初心者の嘘だと思って聞いてください・・・ λ 7
  8. 8. λ λ 8
  9. 9. 휷 λ 9 今回やること
  10. 10. (Lambdaだけで) 純LISPのような ナニかを作る λ 10
  11. 11. λ 11
  12. 12. 予約語4つの言語 でLISPを作る lambda, ., quote, ::= λ 12
  13. 13. どんな言語?? λ 13
  14. 14. どんな言語?? • 今回は、Lambda項を用いたLambda計算を指す λ 14
  15. 15. どんな言語?? • 今回は、Lambda項を用いたLambda計算を指す • こういうやつ: λ푧. 푧 λ푥푦. 푥 λ푥푦푧. 푧푥푦 푎 푏 훽 λ푥푦푧. 푧푥푦 푎 푏 λ푥푦. 푥 훽 λ푧. 푧푎푏 λ푥푦. 푥 훽 λ푥푦. 푥 푎 푏 훽 푎 λ 15
  16. 16. どんな言語?? • 今回は、Lambda項を用いたLambda計算を指す • こういうやつ: λ푧. 푧 λ푥푦. 푥 λ푥푦푧. 푧푥푦 푎 푏 훽 λ푥푦푧. 푧푥푦 푎 푏 λ푥푦. 푥 훽 (λ푧. 푧푎푏) λ푥푦. 푥 훽 (λ푥푦. 푥) 푎 푏 훽 푎 λ 16
  17. 17. どんな言語?? • 今回は、Lambda項を用いたLambda計算を指す • こういうやつ: λ푧. 푧 λ푥푦. 푥 λ푥푦푧. 푧푥푦 푎 푏 훽 λ푥푦푧. 푧푥푦 푎 푏 λ푥푦. 푥 훽 (λ푧. 푧푎푏) λ푥푦. 푥 훽 (λ푥푦. 푥) 푎 푏 훽 푎 ( ゚Д゚)ハァ? λ 17
  18. 18. どんな言語?? • Lambda項を言語らしく起こした(!) λ 18
  19. 19. どんな言語?? • Lambda項を言語らしく起こした(!) ( ^ω^) <ここに項があるじゃろ? ⊃ λ푥푦. 푥 푎 푏 ⊂ λ 19
  20. 20. どんな言語?? • Lambda項を言語らしく起こした(!) ( ^ω^) <ここに項があるじゃろ? ⊃ λ푥푦. 푥 푎 푏 ⊂ ( ՞ਊ ՞) <こうじゃ! ⊃ ((lambda x.(lambda y.x)) a) b) ⊂ λ 20
  21. 21. どんな言語?? • Lambda項を言語らしく起こした(!) ( ^ω^) <ここに項があるじゃろ? ⊃ λ푥푦. 푥 푎 푏 ⊂ _人人人人_ > 腕が<  ̄Y^Y^Y ̄ ( ՞ਊ ՞) <こうじゃ! ⊃ ((lambda x.(lambda y.x)) a) b) ⊂ λ 21
  22. 22. 処理系書きました!!1 • 対話型の処理系 • ラムダ項を与えるとラムダ計算します λ 22 URL : http://lmd.maruuusa.tk/ Github : maruuusa83/lambda_evaluator
  23. 23. 予約語の数 "lambda" { return (LAMBDA); } "quote " { return (QUOTE); } "::=" { return (DEFUN); } "." { return (PERIOD); } "(" { return (LP); } ")" { return (RP); } "n" { return (CR); } [a-z][0-9]? { lambda.l yylval.identifier = lambda_create_identifier(yytext); return (IDENTIFIER); } [_A-Z][_A-Za-z0-9]* { yylval.name = lambda_create_identifier(yytext); return (NAME); } λ 23
  24. 24. 予約語の数 "lambda" { return (LAMBDA); } "quote " { return (QUOTE); } "::=" { return (DEFUN); } "." { return (PERIOD); } "(" { return (LP); } ")" { return (RP); } "n" { return (CR); } [a-z][0-9]? { lambda.l yylval.identifier = lambda_create_identifier(yytext); return (IDENTIFIER); } [_A-Z][_A-Za-z0-9]* { yylval.name = lambda_create_identifier(yytext); return (NAME); } λ 24
  25. 25. 純LISPってなんぞ λ 25
  26. 26. 純LISPってなんぞ • 最小限の関数とプリミティブのみのLISP • これは自身の処理系を記述できる最低限の構 成 λ 26
  27. 27. 純LISPってなんぞ • 最小限の関数とプリミティブのみのLISP • これは自身の処理系を記述できる最低限の構 成 λ 27 5つの基本関数 cons, car, cdr eq, atom 4つの特殊形式 lambda, cond, define, quote
  28. 28. Lambda計算について 휷
  29. 29. Lambda項について • Lambda計算の対象となるのはLambda項のみ λ 29
  30. 30. Lambda項について • Lambda計算の対象となるのはLambda項のみ • 変数푥0,푥1,푥2,…は、lambda項 • 푥が変数、푀がlambda項のとき、(λ푥. 푀)はlambda項 • 푀と푁がともにlambda項のとき、(푀 푁)はlambda項 λ 30
  31. 31. Lambda項について • Lambda計算の対象となるのはLambda項のみ • 変数푥0,푥1,푥2,…は、lambda項 • 푥が変数、푀がlambda項のとき、(λ푥. 푀)はlambda項 • 푀と푁がともにlambda項のとき、(푀 푁)はlambda項 (項を定義するだけではよくわからない・・・) λ 31
  32. 32. Lambda計算規則 λ 32
  33. 33. Lambda計算規則 • β-簡約 項がλ푥. 푀 푁のような形をとるとき、 項푀の内部にある変数푥を푁で置き換える • 代入は次のように定義する • 푥 푥 ≔ 푁 ≡ 푁 • 푦 푥 ≔ 푁 ≡ 푦 • 퐿 푀 푥 ≔ 푁 ≡ 퐿 푥 ≔ 푁 푀 푥 ≔ 푁 • λ푦. 푀 푥 ≔ 푁 ≡ λ푧. ( 푀 푦 ≔ 푧 푥 ≔ 푁 ) λ 33
  34. 34. 計算例 ((lambda x.x) a) -> (a) 単純に代入 λ 34
  35. 35. 計算例 ((lambda x.x) a) -> (a) 単純に代入 何でも代入できる ((lambda x.x) (lambda y.y)) -> (lambda y.(y)) λ 35
  36. 36. 計算例 ((lambda x.x) a) -> (a) 単純に代入 何でも代入できる ((lambda x.x) (lambda y.y)) -> (lambda y.(y)) 変数名が衝突すると その先置換しない ((lambda x.(lambda x.x)) a) -> (lambda x.(x)) λ 36
  37. 37. 間違えやすい例 X(x y z) ○((x y) z) 含めるのは2項のみ。 基本は左側結合 λ 37
  38. 38. 間違えやすい例 X(x y z) ○((x y) z) 含めるのは2項のみ。 基本は左側結合 X(lambda xy.yx) ○(lambda x.(lambda y.(y x))) 省略は認めていない λ 38
  39. 39. 間違えやすい例 X(x y z) ○((x y) z) 含めるのは2項のみ。 基本は左側結合 X(lambda xy.yx) ○(lambda x.(lambda y.(y x))) X(lambda x.(x)) ○(lambda x.x) 省略は認めていない ごめんなさい、 処理系の仕様です; λ 39
  40. 40. LISPの定義:特殊形式 휷 λ 40
  41. 41. 必要な特殊形式 • lambda, quote, define, condが必要
  42. 42. 必要な特殊形式 • lambda, quote, define, condが必要 • quoteは「評価しない」を指示 • (quote ((lambda x.x) a)) -> ((lambda x.(x)) (a))
  43. 43. 必要な特殊形式 • lambda, quote, define, condが必要 • quoteは「評価しない」を指示 • (quote ((lambda x.x) a)) -> ((lambda x.(x)) (a)) • defineは無名関数に名前を与える • FUNC ::= (lambda x.x) • (FUNC a) -> (a)
  44. 44. 必要な特殊形式 • lambda, quote, define, condが必要 • quoteは「評価しない」を指示 • (quote ((lambda x.x) a)) -> ((lambda x.(x)) (a)) • defineは無名関数に名前を与える • FUNC ::= (lambda x.x) • (FUNC a) -> (a) あとはcondだけ!(笑)
  45. 45. condとな • cond:C言語でいうswitch-case文 • かなり複雑になりそうなのでIF文に・・・ λ 45
  46. 46. condとな • cond:C言語でいうswitch-case文 • かなり複雑になりそうなのでIF文に・・・ • λ푥푦푞. 푞푥푦って感じ? q:選択子x:THEN y:ELSE • IF ::= (lambda x.(lambda y.(lambda q.((q x) y)))) λ 46
  47. 47. condとな • cond:C言語でいうswitch-case文 • かなり複雑になりそうなのでIF文に・・・ • λ푥푦푞. 푞푥푦って感じ? q:選択子x:THEN y:ELSE • IF ::= (lambda x.(lambda y.(lambda q.((q x) λ 47 y)))) • TRUE ::= (lambda x.(lambda y.x)) • FALSE ::= (lambda x.(lambda y.y))
  48. 48. condとな • cond:C言語でいうswitch-case文 • かなり複雑になりそうなのでIF文に・・・ TRUEは一つ目の引数、 FALSEは二つ目の引数を返す • λ푥푦푞. 푞푥푦って感じ? q:選択子x:THEN y:ELSE • IF ::= ということに注目!!! (lambda x.(lambda y.(lambda q.((q x) y)))) • TRUE ::= (lambda x.(lambda y.x)) • FALSE ::= (lambda x.(lambda y.y)) λ 48
  49. 49. condとな • ついでに論理演算子も定義する λ 49
  50. 50. condとな • ついでに論理演算子も定義する • NOT ::= (lambda q.((q FALSE) TRUE)) λ 50
  51. 51. condとな • ついでに論理演算子も定義する • NOT ::= (lambda q.((q FALSE) TRUE)) • AND ::= (lambda p.(lambda q.((p q) FALSE))) • OR ::= (lambda p.(lambda q.((p TRUE) q))) λ 51
  52. 52. LISPの定義:標準関数 휷 λ 52
  53. 53. cons, car, cdr • car, cdrはλ푥푦. 푥とかλ푥푦. 푦という感じ?
  54. 54. cons, car, cdr • car, cdrはλ푥푦. 푥とかλ푥푦. 푦という感じ? • (CAR ((CONS a) b))という感じにしたい • が、最左(名前呼び)戦略なので CARの評価時点でCONSが未評価になってしまう
  55. 55. cons, car, cdr • car, cdrはλ푥푦. 푥とかλ푥푦. 푦という感じ? • (CAR ((CONS a) b))という感じにしたい • が、最左(名前呼び)戦略なので CARの評価時点でCONSが未評価になってしまう • λ푧. (푧 λ푥푦. 푥) としてCONSを左へ! • CAR ::= (lambda z.(z (lambda x.(lambda y.x))))
  56. 56. cons, car, cdr • consに値呼びを名前呼びに戻す力を持たせる • λ푥푦푧. 푧푥푦 として最後に評価項をとる CONS ::= (lambda x.(lambda y.(lambda z.((z x) y)))) λ 56
  57. 57. eqとequalの定義・・・ λ 57
  58. 58. eqとequalの定義・・・ かなりややこしい! (時間がない!!!!) λ 58
  59. 59. データ構造の定義:LIST • eq, atomを定義したい • が、(M N)がデータ構造だとかなり扱いにくい • CONSの定義を右側結合でそのまま使う! • ただし、必ず末尾にNIL::=FALSEを含む λ 59
  60. 60. データ構造の定義:LIST • eq, atomを定義したい • が、(M N)がデータ構造だとかなり扱いにくい • CONSの定義を右側結合でそのまま使う! • ただし、必ず末尾にNIL::=FALSEを含む • < 푀 > ≡ (퐶푂푁푆 푀 푁퐼퐿) = λ푧. ( 푧 푀 푁퐼퐿) • < 푀, 푁 > ≡ (퐶푂푁푆 푀 < 푁 >) 훽 퐶푂푁푆 푀 (λ푧. ( 푧 푁 푁퐼퐿) 훽 λ푧. ( 푧 푀 푧. 푧 푁 푁퐼퐿 ) λ 60
  61. 61. データ構造の定義:LIST • eq, atomを定義したい • が、(M N)が定デ義ータす構る造LISPだとかでなは り扱いにくい • CONSの定義を右側結合でそのまま使う! 全てのデータはLISTで表現! • ただし、必ず末尾にNIL::=FALSEを含む GEN_ATOM ::= (lambda x.((CONS x) NIL)) ADD_LIST ::= • < 푀 > ≡ (퐶푂푁푆 푀 푁퐼퐿) = λ푧. ( 푧 푀 푁퐼퐿) • < 푀, 푁 > ≡ (퐶푂푁푆 푀 < 푁 >) (lambda l1.(lambda l2.((CONS l2) 훽 퐶푂푁푆 푀 (λ푧. ( 푧 푁 푁퐼퐿) 훽 λ푧. ( 푧 푀 푧. 푧 푁 푁퐼퐿 ) λ 61 l1)))
  62. 62. データ構造の定義:LIST • eq, atomを定義したい • が、(M N)が定デ義ータす構る造LISPだとかでなは り扱いにくい • CONSの定義を右側結合でそのまま使う! 全てのデータはLISTで表現! • ただし、必ず末尾にNIL::=FALSEを含む GEN_ATOM ::= (lambda x.((CONS x) NIL)) ADD_ATOM ::= • < 푀 > ≡ (퐶푂푁푆 푀 푁퐼퐿) = λ푧. ( 푧 푀 푁퐼퐿) • < 푀, 푁 > ≡ (퐶푂푁푆 푀 < 푁 >) (lambda l1.(lambda l2.((CONS l2) 훽 퐶푂푁푆 푀 (λ푧. ( 푧 푁 푁퐼퐿) 훽 λ푧. ( 푧 푀 푧. 푧 푁 푁퐼퐿 ) λ 62 l1)))
  63. 63. atomの定義 • アトムは、lambdaを一枚はがすとNIL • リストは、lambdaを1枚はがしてもリスト • リストならFALSEを返す感じの方針 λ 63
  64. 64. atomの定義 • アトムは、lambdaを一枚はがすとNIL • リストは、lambdaを1枚はがしてもリスト • リストならFALSEを返す感じの方針 • IS_LIST ::= (lambda x. ((IF (lambda xyz.TRUE) FALSE) (CDR x) )) λ 64
  65. 65. atomの定義 • アトムは、lambdaを一枚はがすとNIL • リストは、lambdaを1枚はがしてもリスト • リストならFALSEを返す感じの方針 • IS_LIST ::= (lambda x. ((IF (lambda xyz.TRUE) FALSE) (CDR x) )) λ 65
  66. 66. atomの定義 • アトムは、lambdaを一枚はがすとNIL • リストは、lambdaを1枚はがしてもリスト • リストならFALSEを返す感じの方針 • IS_LIST ::= (lambda x. ((IF (lambda xyz.TRUE) FALSE) (CDR x) )) λ 66
  67. 67. atomの定義 • アトムは、lambdaを一枚はがすとNIL • リストは、lambdaを1枚はがしてもリスト • リストならFALSEを返す感じの方針 • IS_LIST ::= (lambda x. ((IF (lambda xyz.TRUE) FALSE) (CDR x) )) < M, N > ::= (lambda z.((z M) (lambda z.((z n) NIL))) λ 67
  68. 68. atomの定義 • アトムは、lambdaを一枚はがすとNIL • リストは、lambdaを1枚はがしてもリスト • リストならFALSEを返す感じの方針 • IS_LIST ::= (lambda x. ((IF (lambda xyz.TRUE) FALSE) (CDR x) )) < M, N > ::= (lambda z.((z M) (lambda z.((z n) NIL))) λ 68
  69. 69. • アトムは、lambdaを一枚はがすとNIL • リストは、lambdaを1枚はがしてもリスト • リストならFALSEを返す感じの方針 • IS_LIST ::= (lambda x. ((IF (lambda xyz.TRUE) FALSE) (CDR x) )) atomの定義 λ 69
  70. 70. atomの定義 • アトムは、lambdaを一枚はがすとNIL • リストは、lambdaを1枚はがしてもリスト • リストならFALSEを返す感じの方針 • IS_LIST ::= (lambda x. ((IF (lambda xyz.TRUE) FALSE) (CDR x) )) • ATOM ::= (lambda x. (NOT (IS_LIST x)) ) λ 70
  71. 71. データの定義 • eqを定義したい・・・ • 二つの引数が等しいか調べる • 識別子が同じか調べるのは言語仕様レベルの話? λ 71
  72. 72. データの定義 • eqを定義したい・・・ • 二つの引数が等しいか調べる • 識別子が同じか調べるのは言語仕様レベルの話? • 値を定義して、同じか調べられるようにする ⇒チャーチ数 λ 72
  73. 73. チャーチ数とな • 関数適用の回数で数値を表現する • 0 ≔ λ푠푧. 푧, 1 ≔ λ푠푧. 푠푧, 2 ≔ λ푠푧. 푠 푠 푧 , … λ 73
  74. 74. チャーチ数とな • 関数適用の回数で数値を表現する • 0 ≔ λ푠푧. 푧, 1 ≔ λ푠푧. 푠푧, 2 ≔ λ푠푧. 푠 푠 푧 , … • 2つ目の引数zに1つ目の引数sをN回適用する • FALSEと0の表現が同じであることに注目 λ 74
  75. 75. チャーチ数の比較 • IS_ZERO ::= ((IF (lambda x.FALSE) TRUE)) • atomとほぼ同じ形(読み捨てが3個→1個に) λ 75
  76. 76. チャーチ数の比較 • MとNの大小比較! • trueをN個生成して、M回IFに食わせる ⇒大きさの比較ができる! λ 76
  77. 77. チャーチ数の比較 • MとNの大小比較! • trueをN個生成して、M回IFに食わせる ⇒大きさの比較ができる! • N_TRUE_APP ::= (lambda n.(lambda z. (n (lambda z.((CONS TRUE) z))) ) λ 77
  78. 78. チャーチ数の比較 • MとNの大小比較! • trueをN個生成して、M回IFに食わせる ⇒大きさの比較ができる! • N_TRUE_APP ::= (lambda n.(lambda z. (n (lambda z.((CONS TRUE) z))) ) (lambda f.(lambda x.(f (f…(f a)))…) λ 78
  79. 79. チャーチ数の比較 • MとNの大小比較! • trueをN個生成して、M回IFに食わせる ⇒大きさの比較ができる! • N_TRUE_APP ::= (lambda n.(lambda z. (n (lambda z.((CONS TRUE) z))) ) • GREATER ::= (lambda m.(lambda n. ((n (lambda z.(((IF (CDR z)) z) (CAR z))) (N_TRUE_APP m) ((CONS FALSE) FALSE) )) λ 79
  80. 80. チャーチ数の比較 • MとNの大小比較! • trueをN個生成して、M回IFに食わせる ⇒大きさの比較ができる! • N_TRUE_APP ::= (lambda n.(lambda z. (n (lambda z.((CONS TRUE) z))) ) • GREATER ::= (lambda m.(lambda n. ((n (lambda z.(((IF (CDR z)) z) (CAR z))) (N_TRUE_APP m) ((CONS FALSE) FALSE) )) λ 80
  81. 81. チャーチ数の比較 • MとNの大小比較! • trueをN個生成して、M回IFに食わせる ⇒大きさの比較ができる! • N_TRUE_APP ::= (lambda n.(lambda z. (n (lambda z.((CONS TRUE) z))) ) • GREATER ::= (lambda m.(lambda n. ((n (lambda z.(((IF (CDR z)) z) (CAR z))) (N_TRUE_APP m) ((CONS FALSE) FALSE) )) λ 81
  82. 82. チャーチ数の比較 • MとNの大小比較! • trueをN個生成して、M回IFに食わせる ⇒大きさの比較ができる! • N_TRUE_APP ::= (lambda n.(lambda z. (n (lambda z.((CONS TRUE) z))) ) • GREATER ::= (lambda m.(lambda n. ((n (lambda z.(((IF (CDR z)) z) (CAR z))) (N_TRUE_APP m) ((CONS FALSE) FALSE) )) λ 82
  83. 83. 比較ができるからeqができる • 等しければTRUEが返る ⇒どちらで比較してもTRUEならば等しい! λ 83
  84. 84. 比較ができるからeqができる • 等しければTRUEが返る ⇒どちらで比較してもTRUEならば等しい! • EQ ::= (lambda n.(lambda m. ((AND (NOT ((GREATER n) m))) (NOT ((GREATER m) n))) ) λ 84
  85. 85. 比較ができるからeqができる • 等しければTRUEが返る ⇒どちらで比較してもTRUEならば等しい! • EQ ::= (lambda n.(lambda m. ((AND (NOT ((GREATER n) m))) (NOT ((GREATER m) n))) ) SIMPLE!! λ 85
  86. 86. 휷 まとめ λ 86
  87. 87. IFとそれに伴う諸々(COND) • IF ::= (lambda x.(lambda y.(lambda q.((q x) y)))) • TRUE ::= (lambda x.(lambda y.x)) • FALSE ::= (lambda x.(lambda y.y)) • NOT ::= (lambda q.((q FALSE) TRUE)) • AND ::= (lambda p.(lambda q.((p q) FALSE))) • OR ::= (lambda p.(lambda q.((p TRUE) q)))
  88. 88. CONS, CAR, CDR • CONS ::= (lambda x.(lambda y.(lambda z.((z x) y)))) • CAR ::= (lambda z.(z TRUE)) • CDR ::= (lambda z.(z FALSE)) λ 88
  89. 89. LISTとATOM • GEN_ATOM ::= (lambda x.((CONS x) NIL)) • ADD_ATOM ::= (lambda l1.(lambda l2.((CONS l2) l1))) • IS_LIST ::= (lambda x. ((IF (lambda xyz.TRUE) FALSE) (CDR x) )) • ATOM ::= (lambda x.(NOT (IS_LIST x)) ) λ 89
  90. 90. チャーチ数とEQ • N_TRUE_APP ::= (lambda n.(lambda z. (n (lambda z.((CONS TRUE) z))) ) • GREATER ::= (lambda m.(lambda n. ((n (lambda z.(((IF (CDR z)) z) (CAR z))) (N_TRUE_APP m) ((CONS FALSE) FALSE) )) • EQ ::= (lambda n.(lambda m. ((AND (NOT ((GREATER n) m))) (NOT ((GλREATER m) n))) ) 90
  91. 91. 予約語4つの言語 でLISPを作る lambda, ., quote, ::= (16行くらい?) λ 91
  92. 92. λ 92
  93. 93. λ 93
  94. 94. Thank you for listening marusa (@maruuusa83) λ 94

×