今日の話題 情報科学概論Ⅱ プログラム言語と型システム メタプログラミング 1. 2. 3. 亀山 幸義 http://logic.cs.tsukuba.ac.jp/~kam プログラム特化とは プログラム特化の技法 メタプログラミング言語 1 2 べき乗の関数(定義) 1. プログラム特化とは power(x, n) = x if n=1 x * power(x, n – 1) if n>1 power (5,3)=5*power(5,2) =5*(5*power(5,1))=5*(5*5)=125 3 べき乗の関数(C言語) 4 べき乗の関数(in OCaml) let rec power x n = if n = 1 then x else x * (power x (n - 1)) int power(int x, n) { if (n == 1) return x; else return x*power(x, n–1); } 関数型言語OCaml プログラム=関数(または、部分関数) 変数の宣言(型宣言)が不要。 5 6 1 べき乗の関数(問題1) べき乗の関数(12乗) let rec power x n = if n=1 then x else x * (power x (n - 1)) let power12 x = x*x*x*x*x*x*x*x*x*x*x*x (power12 x) は (power x 12)より高速 問題1: 様々な x に対して、その12乗を計算 したい。どうすれば効率的に計算でき るか? 1. 2. 3. 関数呼出しがない 条件式(if)や比較(n=1)がない 引数nの値を覚えるためのメモリも不要 7 プログラム特化 program specialization べき乗の関数(問題2) let rec power x n = if n=1 then x else x * (power x (n - 1)) let power12 x = x*x*x*x*x*x*x*x*x*x*x*x 問題2: power関数と「n=12」という情報から power12関数を自動的に得る方法は? 8 power12関数 power関数 特化された プログラム 一般的な プログラム 実行 結果 4096 入力データ n=12 入力データ x=2 9 10 特化の方法(1) 特化の方法(2) let rec power x n = if n = 1 then x else x * (power x (n - 1)) let rec power x n = if n = 1 then x else x * (power x (n - 1)) プログラム特化における仮定 nの値: この時点で分かっている xの値: この時点では分からない n のみに依存した計算 (xに依存しな い計算)は、実行する。 11 12 2 特化の方法(3) 特化の方法(3) let rec power x n = if n = 1 then x else x * (power x (n - 1)) let rec power x n = if n = 1 then x else x * (power x (n - 1)) n のみに依存した計算 (xに依存しな い計算)は、実行する。 n のみに依存した計算 (xに依存しな い計算)は、実行する。 13 14 特化の方法(4) 特化の方法(5) let rec power x n = if n = 1 then x else x * (power x (n - 1)) let rec power x n = if n = 1 then x else x * (power x (n - 1)) 赤色: 今、できる計算(静的) 青色: 後に残す計算(動的) n のみに依存した計算 (xに依存しな い計算)は、実行する。 15 べき乗関数の特化 16 べき乗関数の特化 let rec power x n = if n = 1 then x else x * (power x (n - 1)) let rec power x n = if n = 1 then x else x * (power x (n - 1)) power x 12 → if 12=0 then 1 else x * (power x (12-1)) → x * (power x 11) → x * (x * (power x 10)) →... → x*x*x*x*x*x*x*x*x*x*x*x powerの再帰呼び出しも赤色(静的)とする。 ただし、関数の色分けはそう単純にはできな いので、これは暫定的なもの(後述) 17 18 3 プログラム特化(部分計算) 特化された関数の利用 let power12 x = x*x*x*x*x*x*x*x*x*x*x*x power12 2 → 4096 power12 3 → 531441 power関数 一般的な プログラム power12関数 プログラム 特化器 特化された プログラム 実行 結果 4096 特化されたプログラム 1.実行性能が高い(高速、低メモリ) 2.特定のケースにしか使えない。 記号計算 入力データ 入力データ n=12 x=2 19 20 プログラム特化は メタプログラミングの一例 メタプログラム 2. プログラム特化の技法 プログラムを入力として受け取ったり、 プログラムを生成して返したりするプログラム メタプログラムの例 コンパイラ、インタプリタ、構文解析器生成プログラム 実は我々の身の回りにあふれている 21 22 特化の方法≠プログラム塗り分け -map関数の例- 特化の方法=赤青の塗り分け? let rec power x n = if n = 1 then x else x * (power x (n - 1)) let inc x = x + 1 ;; map inc [1; 2; 3] ;; → [2; 3; 4] map inc [10; 20; 30; 40; 50] ;; → [11; 21; 31; 31; 51] 赤色: 今、できる計算(静的) 青色: 後に残す計算(動的) 23 24 4 特化の方法≠プログラム塗り分け -map関数の例- 特化の方法の1つ=型の塗り分け map func lst に対する特化の可能性 1. 2. 3. (i) 10: 整数型 (int) “abc” : 文字列型 (string) [1; 2; 3] : 「整数のリスト」の型 (int list) xi : int のとき、[x1; x2; x3] : int list xi : int のとき、[x1; x2; x3] : int list それ以外に lst : int list lst は動的 lst の要素は動的だが、長さは静的 lst は静的 func は。。。 すべての可能性を、プログラムに対する2色の塗り分け では表現できない。 25 型システム(1) 型システム(2) let rec power x n = if n = 1 then x else x * (power x (n - 1)) power : int → int → int, 26 x : int, e1 : int e2 : int e1 - e2 : int n : int のもとで n : int 1 : int n-1 : int n-1 : int power x (n-1) : int if n=1 then x else … : int 27 型システム(3) f : a→b f e : 28 型システム(4) let rec power x n = if n = 1 then x else x * (power x (n - 1)) e :a b power : int → (int → int) x : int power x : int → int power x n : int power : int → int → int, x : int, n : int n : int if n=1 then x else x * (power …) : int 29 30 5 型推論(1) 型推論(2) let rec power x n = if n = 1 then x else x * (power x (n - 1)) let rec power x n = if n = 1 then x else x * (power x (n - 1)) プログラム(型についての情報なし)から、 プログラム全体の型を推論しつつ、型が整合するかの 検査をすることを 型推論 (type inference) 型推論アルゴリズムは、主に、関数型言語で発展してきた。 Hindley-Milner (Damas-Milner)の型推論アルゴリズム ML言語の中核部分に対する完全に自動的な型推論を 行う。 → 多くのプログラム言語の型推論の基礎 という。 31 プログラム言語と型システム 32 MLの型推論 型の整合性を静的に(プログラム実行前に)チェッ クする → エラーを、早い段階で、発見することができる。 (ある種の信頼性の保証) 33 色付きの型システム(1) このページは、MLの型推論がすご い!と言いたいための例です。詳 細は今理解する必要はありません。 let rec f x = f (f (f (f (x+1))))) → f : int -> int (* n回適用した f(f(f(…f(x)…))) を計算する*) Let rec iter f n x = if n = 0 then x else f (iter f (n-1) x) → iter : (α -> α) -> int -> α -> α (* f と g を関数合成する*) let compose f g x = g (f x) → compose : (α->β) -> (β->γ) -> (α->γ) 34 色付きの型システム(2) let rec power x n = if n = 1 then x else x * (power x (n - 1)) e1 : int e2 : int e1 - e2 : int power : int → int → int x n 返り値 e1 : int e2 : int e1 - e2 : int 35 36 6 色付きの型システム(3) 色付きの型システム(4) f : a→b e :a f @e : b power : int → (int → int) x : int power @ x : int → int n : int (power @ x) @ n : int f : a→b e :a f @e : b a,b は赤でも青でもよいが、 色が一貫していなければならない。 38 37 プログラム特化の技法 型に色を付ける。 あとは、通常の、型システム上の型推論を行う。 (赤いintと青いintは別の型とみなす。) 3.メタプログラミング言語 それだけでよい。 関数型言語と型システムを基礎として、プログラ ム特化(および、一般のメタプログラミング)は発展 してきた。 Lisp/Scheme, MetaOCaml, template Haskell 39 メタプログラミングのための言語 40 MetaOCamlプログラミング マルチステージプログラミング言語MetaOCaml let rec power x n = if n = 1 then x else .< .~x * .~(power x (n – 1)) >. power : int code → int → int code int → int → int 41 power .<5>. 12 → .<5 * 5 * 5 * … * 5>. power .<x>. 12 → エラー (変数や型整合性のチェック) .<fun x -> .~(power .<x>. 12)>. → .<fun x -> x * x * … * x>. let f = run .<fun x -> .~(power .<x>. 12)>. In f2 → 4096 42 7 メタプログラミング言語 プログラム言語と型システム 型の整合性を静的にチェックする let rec power x n = if n = 1 then x else .< .~x * .~(power x (n – 1))>. let rec power_gen x n = if n = 1 then x else if even(n) then .<square .~(power_gen x (n/2))>. else .< .~x * .~(power_gen x (n-1))>. → power_gen .<2>. 5 = .<2*(square (square 2)>. MetaOCamlにおいては、 プログラム生成器の信頼性だけでなく、 生成されるプログラムのある種の信頼性を、 プログラム生成前に保証する .<1 + 2>. → .< 1 + 2>. (コード生成) let x = .<1+2>. in .< .~x * 3 >. → .< (1+2) * 3 >. (コード合成) run .< 1 + 2> → 3 (コード実行) 43 メタプログラミング言語の応用例 44 メタプログラミング言語の応用例 領域特化言語(DSL)の処理系(インタプリタ)の高速化 [Taha et al. 2004] Tahaらの例: DSL=小さな関数型言語 MetaOCamlで記述したインタプリタを、ステージ化 →たとえば、階乗計算プログラムで約7倍の高速化 数値計算ライブラリの保守性の向上 [Carette et al. 2005] Maple(数値計算パッケージ)における「ガウスの消 去法アルゴリズム」の実装 なんと30種類以上も、ほとんど同じアルゴリズムの実装 が、はいっていた 同じアルゴリズムだが、行列要素が実数か複素数か、な ど様々なパラメータによって、ほんの少し違う実装たち。 →プログラム特化の形で書き直した。 人間が保守するのは1つのアルゴリズム 実際にユーザが使うのは特化された30通りのプログラム 「インタプリタ」 を 「階乗計算プログラム」に特化した。 45 46 メタプログラミングの研究 メタプログラミングの研究 亀山らの研究 MetaOCaml の型システムで安全性が保証され ているのは、純粋な関数型言語の部分(コア)のみ 実際には副作用がたくさんある ref型 (書き換え可能な変数、状態) 制御 (exception, 継続操作) 入出力 → 副作用を持つメタプログラミング言語に対する安 全性、信頼性の確保(型システムの設計、実装) 47 ・理論的な安全性の保証 プログラムを実際に生成する前に、おかしなプロ グラムが生成されないことを保証したい。 ・プログラミング技法 プログラム生成における効率化技法の取り込み ・現実への応用 高性能計算(行列計算、隠れマルコフモデルのア ルゴリズム、レイトレーシングなど)における、プロ グラム生成を系統化。 48 8 まとめ 今日の話題 プログラム特化(部分計算) メタプログラム(プログラムを作るプログラム) プログラム言語の研究 保守性や拡張性と、実行効率の両立 安全性や信頼性の保証 型システムと関数型言語 49 9
© Copyright 2024 ExpyDoc