More Related Content
Similar to (Lambdaだけで)純LISPのようなナニかを作る (20)
More from Daichi Teruya (7)
(Lambdaだけで)純LISPのようなナニかを作る
- 2. λ 2
自己紹介
• まるさ(@maruuusa83)
• 沖縄高専メディア科5年生
- 6. アジェンダ
• 自己紹介
• 今回やることとか色々
• 特殊形式の定義
• CONS, CAR, CDR
• COND
• データ構造の定義
• CONDの定義
• EQ
• 値の定義
• EQの定義
λ 6
- 22. 処理系書きました!!1
• 対話型の処理系
• ラムダ項を与えるとラムダ計算します
λ 22
URL :
http://lmd.maruuusa.tk/
Github :
maruuusa83/lambda_evaluator
- 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. 予約語の数
"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
- 33. Lambda計算規則
• β-簡約
項がλ푥. 푀 푁のような形をとるとき、
項푀の内部にある変数푥を푁で置き換える
• 代入は次のように定義する
• 푥 푥 ≔ 푁 ≡ 푁
• 푦 푥 ≔ 푁 ≡ 푦
• 퐿 푀 푥 ≔ 푁 ≡ 퐿 푥 ≔ 푁 푀 푥 ≔ 푁
• λ푦. 푀 푥 ≔ 푁 ≡ λ푧. ( 푀 푦 ≔ 푧 푥 ≔ 푁 )
λ 33
- 35. 計算例
((lambda x.x) a)
-> (a)
単純に代入
何でも代入できる
((lambda x.x) (lambda y.y))
-> (lambda y.(y))
λ 35
- 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
- 38. 間違えやすい例
X(x y z)
○((x y) z)
含めるのは2項のみ。
基本は左側結合
X(lambda xy.yx)
○(lambda x.(lambda y.(y x)))
省略は認めていない
λ 38
- 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
- 42. 必要な特殊形式
• lambda, quote, define, condが必要
• quoteは「評価しない」を指示
• (quote ((lambda x.x) a)) -> ((lambda x.(x))
(a))
- 43. 必要な特殊形式
• lambda, quote, define, condが必要
• quoteは「評価しない」を指示
• (quote ((lambda x.x) a)) -> ((lambda x.(x))
(a))
• defineは無名関数に名前を与える
• FUNC ::= (lambda x.x)
• (FUNC a) -> (a)
- 44. 必要な特殊形式
• lambda, quote, define, condが必要
• quoteは「評価しない」を指示
• (quote ((lambda x.x) a)) -> ((lambda x.(x))
(a))
• defineは無名関数に名前を与える
• FUNC ::= (lambda x.x)
• (FUNC a) -> (a)
あとはcondだけ!(笑)
- 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. 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
- 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
- 54. cons, car, cdr
• car, cdrはλ푥푦. 푥とかλ푥푦. 푦という感じ?
• (CAR ((CONS a) b))という感じにしたい
• が、最左(名前呼び)戦略なので
CARの評価時点でCONSが未評価になってしまう
- 55. cons, car, cdr
• car, cdrはλ푥푦. 푥とかλ푥푦. 푦という感じ?
• (CAR ((CONS a) b))という感じにしたい
• が、最左(名前呼び)戦略なので
CARの評価時点でCONSが未評価になってしまう
• λ푧. (푧 λ푥푦. 푥) としてCONSを左へ!
• CAR ::=
(lambda z.(z (lambda x.(lambda
y.x))))
- 56. cons, car, cdr
• consに値呼びを名前呼びに戻す力を持たせる
• λ푥푦푧. 푧푥푦 として最後に評価項をとる
CONS ::=
(lambda x.(lambda y.(lambda z.((z x)
y))))
λ 56
- 59. データ構造の定義:LIST
• eq, atomを定義したい
• が、(M N)がデータ構造だとかなり扱いにくい
• CONSの定義を右側結合でそのまま使う!
• ただし、必ず末尾にNIL::=FALSEを含む
λ 59
- 60. データ構造の定義:LIST
• eq, atomを定義したい
• が、(M N)がデータ構造だとかなり扱いにくい
• CONSの定義を右側結合でそのまま使う!
• ただし、必ず末尾にNIL::=FALSEを含む
• < 푀 > ≡ (퐶푂푁푆 푀 푁퐼퐿) = λ푧. ( 푧 푀 푁퐼퐿)
• < 푀, 푁 > ≡ (퐶푂푁푆 푀 < 푁 >)
훽
퐶푂푁푆 푀 (λ푧. ( 푧 푁 푁퐼퐿)
훽
λ푧. ( 푧 푀 푧. 푧 푁 푁퐼퐿 )
λ 60
- 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. データ構造の定義: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)))
- 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. 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. • アトムは、lambdaを一枚はがすとNIL
• リストは、lambdaを1枚はがしてもリスト
• リストならFALSEを返す感じの方針
• IS_LIST ::= (lambda x.
((IF (lambda xyz.TRUE)
FALSE)
(CDR x) ))
atomの定義
λ 69
- 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
- 72. データの定義
• eqを定義したい・・・
• 二つの引数が等しいか調べる
• 識別子が同じか調べるのは言語仕様レベルの話?
• 値を定義して、同じか調べられるようにする
⇒チャーチ数
λ 72
- 74. チャーチ数とな
• 関数適用の回数で数値を表現する
• 0 ≔ λ푠푧. 푧, 1 ≔ λ푠푧. 푠푧, 2 ≔ λ푠푧. 푠 푠 푧 , …
• 2つ目の引数zに1つ目の引数sをN回適用する
• FALSEと0の表現が同じであることに注目
λ 74
- 77. チャーチ数の比較
• MとNの大小比較!
• trueをN個生成して、M回IFに食わせる
⇒大きさの比較ができる!
• N_TRUE_APP ::=
(lambda n.(lambda z.
(n (lambda z.((CONS TRUE) z))) )
λ 77
- 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. チャーチ数の比較
• 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. チャーチ数の比較
• 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. チャーチ数の比較
• 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. チャーチ数の比較
• 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
- 85. 比較ができるからeqができる
• 等しければTRUEが返る
⇒どちらで比較してもTRUEならば等しい!
• EQ ::= (lambda n.(lambda m.
((AND
(NOT ((GREATER n) m)))
(NOT ((GREATER m) n))) )
SIMPLE!!
λ 85
- 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. 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. 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. チャーチ数と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