Purely Functional Data Structures 10 DataStructural Bootstrapping 20060721
Purely Functional Data Structures 輪講 第 10章 “Data-Structural Bootstrapping” 2006/07/21 いなば kinaba@is. s. u-tokyo. ac. jp
① Structural Decomposition n 実装の中で自分自身を再帰的に使用 ¨ Uniform type ‘a list = Nil | Cons of ‘a * ‘a list ¨ Non-uniform type ‘a seq = Nil | Cons of ‘a * (‘a*’a) seq
注意事項 : Non-Uniform Recursion (Polymorphic Recursion) n このようなデータ型は、MLの型システムでは あまりうまく扱えない type ‘a seq = Nil | Cons of ‘a * (‘a*’a) seq let rec length s = match s with Nil -> 0 | Cons(_, t) -> 1 + 2*(length t) File "test. ml", line 7, characters 36 -37: This expression has type ('a * 'a) seq but is here used with type 'a seq
注意事項 : Non-Uniform Recursion (Polymorphic Recursion) n 方法1 : Coercion type ‘a EP = | type ‘a seq = | n E of ‘a P of ‘a EP * ‘a EP Nil Cons of EP ‘a * ‘a seq 方法2 : Explicit Type Annotation (Haskell) len : : Seq a -> Int len s = case s of Nil -> 0 Cons _ t -> 1 + 2*(len t)
例1 Binary Random-Access List n Rivisited さっきの type ‘a seq = Nil | Cons of ‘a * (‘a*’a) seq は実用上はあまり意味がない。 (サイズ 2 n-1のリストしか表現できない) → Numerical Representation の考え方で → “Bin. Ran. hs”
例1 Binary Random-Access List n Rivisited 第9章の RList と何が違うのか? type ‘a tree = | type ‘a digit = type ‘a rlist = Leaf of ‘a Node of ‘a tree * ‘a tree Zero | One of ‘a tree (‘a digit) list ¨ 本質的な違いはない n cons, head, tail, get, set は O(log n) ¨ Non-Uniform Recursion によって 桁ごとのweightが倍々になっていることを型で保証 n 「次の桁」を得るのが簡単 n
Exercise 10. 2 Zeroless表現 n 前回の「Zeroless 表現」も同様にnonuniform recursionで実現できる ¨ cons, head, tail が amortized O(1) type ‘a seq = Nil | One of ‘a * (‘a*’a) seq | Two of ‘a * (‘a*’a) seq | Three of ‘a * (‘a*’a) seq
例2 Bootstrapped Queues n 復習 : Banker’s Queue type ‘a queue = int * ‘a list lazy_t * int * ‘a list lazy_t let rotate (fl, f, rl, r) = (fl+rl, f @ (rev r), 0, []) n Banker’s Queue の問題点 ¨ Append が Left-Associative に使われる n 計算量的には問題ないが、実用面では少し遅い (((f @ (rev r 1)) @ (rev r 2)) @ (rev r 3)) @. .
例2 Bootstrapped Queues n 実装の概要 type ‘a queue = int * ‘a list lazy_t * (‘a list lazy_t) queue * int * ‘a list lazy_t let rotate (fl, f, m, rl, r) = (fl+rl, f, snoc m (rev r), 0, []) let tail (fl, _: : [], m, rl, r) = (fl-1, head m, tail m, rl, r)
例2 Bootstrapped Queues n 計算量 ¨ (rev r) の suspension が作られるタイミング・ 評価されるタイミングは Banker’s Queue と同じ n rev の分に関しては、Amortized O(1) ¨ snoc, tail は内部Queueの snoc, tail を呼び出す 内部 Queue の長さは O(log n) n よって nest の深さは Hyper-logarithm O(log* n) n snoc, tail は O(log* n) ¨ log* (265536) = 5 なので、実質的に定数 ¨
例3 Catenable Queues n head, tail, cons, snoc, append が Amortized O(1) な Queue ¨ head, n tail, cons ができるのでListとも呼べる 発想はさっきのBootstrapped Queuesと同じ ‘a queue (head, tail, snocが amortized O(1) なもの) が実装済みと仮定 ¨ すでに既存の type ‘a cat = E | C of ‘a * ‘a cat queue → “cat. Q. ml”
例4 Heaps with Efficient Merging n Heaps with Efficient Merging ¨ insert, merge, find. Min : 最悪 O(1) ¨ delete. Min : 最悪 O(log n) n 実装済みと仮定する Heap ¨ insert : 最悪O(1) ¨ mergin, find. Min, delete. Min : O(log n) ¨ たとえば n n Scheduled Binomial Heap (7. 3) Skew Binomial Heap (9. 3. 2)
② Structural Abstraction まとめ(2) n Bootstrapされたデータ構造 type ‘a Boot. Strapped = E | B of ‘a * (‘a Boot. Strapped) Base ¨ 要素追加 ¨ 要素取得 let add x b = join (Base. add x Base. empty) b let get (B(x, _)) = x
② Structural Abstraction まとめ(3) n Bootstrapされたデータ構造 ¨ 二つのBootstrapped構造を「結合」 n Queue の append 、 Heap の merge let join (B(x 1, bs)) b = B(x 1, Base. add b bs) n Structural Abstraction によって、 このような「結合」演算を効率化できる
③ Bootstrapping To Aggregates n 型 t に関する実装を使って t list などに 関する効率的な実装を作る : t を key とするMapを使って、 t list を key とするMapを作る ¨例 module type Map = sig type ‘a map; type key val empty : ‘a map val lookup: key -> ‘a map -> ‘a val bind : key->‘a map->‘a map end
例 Trie n 「リストをKeyとする辞書式順によるMap」 を 「要素をKeyとするMap」 からBootstrap ¨→ “trie. ml” module Trie(B : Map) : Map = struct type key = B. key list type ‘a map = Trie of ‘a option * (‘a map) B. map. . .
おはなし Generalized Tries type ‘a tree = E | T of ‘a * ‘a tree module Trie. Of. Tree(B: Map) : Map = struct type key = B. key tree type ‘a map = Some ‘a * ‘a map B. map let | | | end rec lookup t mp = match t, mp with E, (None, _) -> raise Not_found E, (Some v, _) -> v T(e, a, b) (_, m) -> lookup b (lookup a (B. lookup e m))
- Slides: 25