順序付き線形型に基づく 木構造処理プログラムから ストリーム処理プログラムへの変換 末永 幸平 (東京大学) 児玉 紘一 (東京工業大学) 小林 直樹 (東京工業大学) XML 処理の二つの手法 • 木構造処理 – メモリ上に木を作って処理 – 例: DOM API, XDuce, CDuce • ストリーム処理 – ストリームからデータを読みつつ処理 – 例: SAX 木構造処理 node node leaf leaf leaf leaf 2 3 3 4 ここを記述 メモリ 二次記憶, ネットワーク <node> <leaf>2</leaf> <leaf>3</leaf> </node> <node> <leaf>3</leaf> <leaf>4</leaf> </node> ストリーム処理 メモリ 二次記憶, ネットワーク ここを記述 <node> <leaf>2</leaf> <leaf>3</leaf> </node> <node> <leaf>3</leaf> <leaf>4</leaf> </node> 木構造処理とストリーム処理の比 較 木構造処理 ストリーム処理 記述性 ○ × メモリ効率 × ○ 良い点だけを取りたい 研究の目標 node node leaf leaf leaf leaf 2 メモリ 3 ここを記述 3 4 二次記憶, ネットワーク <node> <leaf>2</leaf> <leaf>3</leaf> </node> <node> <leaf>3</leaf> <leaf>4</leaf> </node> 研究の目標 node node 記述性を保ちつつ leaf leaf leaf leaf メモリ効率を向上させることが可能 3 2 3 4 メモリ 二次記憶, ネットワーク ここに変換 <node> <leaf>2</leaf> <leaf>3</leaf> </node> <node> <leaf>3</leaf> <leaf>4</leaf> </node> 例) 要素全てに1を足した木を作る 関数 • 木構造処理 簡単な変換で済ませたい fix f. λt. case t of leaf x → leaf (x + 1) | node x1 x2 → node (f x1) (f x2) • ストリーム処理 fix f. λt. case read() of leaf → write(leaf); write(read() + 1) | node → write(node); f (); f () 変換できないプログラムの存在 例: 二分木の各ノードの左右を入れ替えるプログラム node leaf 1 node node node leaf leaf leaf 2 3 3 leaf leaf 1 2 正しく変換するためには... • プログラムが正しい順序で部分木にアクセス しなければならない – 正しい順序: 左から右, 深さ優先順 • 解決策: 順序付き線形型を使って制限 – 型付け可能なプログラムは, 部分木に正しい順序 でアクセスしていることを保証 今回の範囲 • 木構造処理とストリーム処理のための 関数型言語を定義 – 対象データを二分木に限定する – ストリーム処理言語ではメモリ上に木を作らせな い • メモリ上に木を構築する拡張を後で行う • 順序付き線形型を用いた型システムを定義 • 前者から後者への変換アルゴリズムを定義 • アルゴリズムの正しさを証明 発表の流れ • • • • • • 対象言語の syntax 型システム 変換アルゴリズムとその正しさ 拡張に向けて 関連研究 まとめ 発表の流れ • • • • • • 対象言語の syntax 型システム 変換アルゴリズムとその正しさ 拡張に向けて 関連研究 まとめ ソース言語とターゲット言語 • ソース言語: 木構造処理 – 入力データを木として処理 – λ計算 + 二分木操作プリミティブ • ターゲット言語: ストリーム処理 – 入力ストリームからデータを読みつつ処理 – λ計算 + ストリーム操作プリミティブ ソース言語の syntax M (項) ::= i (整数) | x | λx.M | M1 M2 | M1 + M2 | fix f. M | leaf M | node M1 M2 | (case M of leaf x → M1 | node x1 x2 → M2) プログラム例 • 各整数に 1 を加えた木を返す関数 fix f. λt. case t of leaf x → leaf (x + 1) | node x1 x2 → node (f x1) (f x2) ターゲット言語の syntax e (項) ::= i | x | λx.e | () | e1 e2 | e1 + e2 | fix f. e | leaf | node node (leaf 1) (leaf 2) は | read e | write e node; leaf; 1; leaf; 2 という ストリームで表現 | (case e of (閉じタグは考えない) leaf → e1 | node → e2) プログラム例 • 各整数に 1 を加えた木を出力する関数 fix f. λx. (case read () of leaf → write leaf; write (read() + 1) | node → write node; f (); f ()) プログラム例 (比較) • ソースプログラム – fix f.λt.(case t of leaf x → leaf (x + 1) | node x1 x2 → node (f x1) (f x2)) • ターゲットプログラム – fix f.λt.(case read() of leaf → write(leaf);write(read()+1) | node → write(node);f ();f ()) 発表の流れ • • • • • • 対象言語の syntax 型システム 変換アルゴリズムとその正しさ 拡張に向けて 関連研究 まとめ 型システム • 順序付き線形型を用いた ソース言語のための型システム • 型付け可能なプログラムに対して以下を保証 – 各ノードを左から右, 深さ優先順に 丁度 1 度ずつアクセス – 出力木をメモリに貯めない 型の syntax τ (型) ::= Int | τ1 → τ2 | Treed d (モード) ::= - (入力) | + (出力) 入力木型 (Tree-) と 出力木型 (Tree+) を区別 二種類の型環境 • (順序なし) 型環境 Γ – { x1:τ1, x2:τ2, ..., xn:τn } (τi ≠ Treed) • 変数の束縛の集合 – 順序が強制されない変数の型情報を保持 • 順序付き線形型環境 Δ – x1:Tree-, x2:Tree-, ..., xn:Tree• 変数の束縛の列 – 「入力木が順番に一度ずつアクセスされる」 ことを表現 型判定 Γ|Δ├M:τ M 中の自由変数が型環境 Γ, Δ に従った型の値に 束縛されるとき, M の評価結果は型τの値となり, 評価中に Δ の順で入力木がアクセスされる 型判定の例 Γ = f : Tree- → Tree+ のとき Γ | x1 : Tree-, x2 : Tree- ├ node (f x1) (f x2) : Tree+ Γ | x1 : Tree-, x2 : Tree- ├ node (f x2) (f x1) : Tree+ 型判定規則 (1/3) Γ|x:Tree -├ x:Tree Γ,x:τ | Ø ├ x:τ - (T-VAR1) (T-VAR2) 順序付き型環境には余計なものは含まれない = 入力木が丁度一回読み込まれる 型判定規則 (2/3) Γ|x:Tree ├M :τ - Γ|Ø├ λx.M :Tree →τ Γ,x:τ1|Ø├M :τ2 Γ|Ø├ λx.M :τ1→τ2 (T-ABS1) (T-ABS2) 型判定規則 (3/3) Γ|Δ1├M1 :Tree + Γ|Δ2├M2 :Tree Γ|Δ1,Δ2├ node M1 M2 :Tree Γ|Δ1├M :Tree Γ,x:Int|Δ2├M1 :τ - 2├M2 :τ Γ|x1:Tree -,x2:Tree ,Δ + (T-NODE) + (T-CASE) Γ|Δ1,Δ2├ case M of leaf x → M1 |node x1 x2 → M2 :τ 型付け例 Γ|Ø├ f : Tree- →Tree+ Γ|x1:Tree-├ x1 : Tree+ Γ|x1:Tree-├ f x1 : Tree+ Γ|x2:Tree-├ f x2 : Tree+ Γ|t:Tree-├ t :TreeΓx:Int|Ø├ leaf (x+1) :Tree+ Γ|x1:Tree-,x2:Tree-├ node (f x1) (f x2) :Tree+ Γ|t:Tree-├case t of leaf x => leaf (x + 1) | node x1 x2 => node (f x1) (f x2) :Tree+ Γ|Ø├λt.(case t of leaf x => leaf (x + 1) | node x1 x2 => node (f x1) (f x2)) :Tree- → Tree+ Ø|Ø├ fix f.λt.(case t of leaf x => leaf (x + 1) | node x1 x2 => node (f x1) (f x2)) :Tree- → Tree+ (ただしΓ= f:Tree- → Tree+とする) 発表の流れ • • • • • • 対象言語の syntax 型システム 変換アルゴリズムとその正しさ 拡張に向けて 関連研究 まとめ 変換アルゴリズム • • • • • • • • • A(x) = x A(i) = i A(λx.M) = λx.A(M) A(M1M2) = A(M1)A(M2) A(M1 + M2) = A(M1) + A(M2) A(fix f.M) = fix f.A(M) A(leaf M) = write(leaf);write(A(M)) A(node M1 M2) -> write(node);A(M1);A(M2) A(case M of leaf x => M1| node x1 x2 => M2) = (case A(M);read() of leaf => let x=read() in A(M1) | node => [()/x1,()/x2]A(M2)) 変換例 A(fix f.λt.(case t of leaf x → leaf (x + 1) | node x1 x2 → node (f x1) (f x2))) = fix f.λt.(case t;read() of leaf => let x = read() in (write(leaf);write(x + 1)) | node => write(node);f ();f ()) 変換の正しさ • 型付け可能なプログラムは, 変換によって 意味が変わらない – 型検査を通れば, 変換によって必ず ストリーム処理のプログラムを得ることが出来る 発表の流れ • • • • • • 対象言語の syntax 型システム 変換アルゴリズムとその正しさ 拡張に向けて 関連研究 まとめ どのような拡張が必要か • 型システムによる制限の緩和 – 入力木のスキップ – 何度もアクセスできる木 今回は この部分を紹介 • 一般の XML への対応 – 子要素の数は一般に 2 より大 – タグの種類の増加 • ストリーム処理で閉じタグも考える必要 拡張の方法 • ターゲット言語 – 入力木をスキップするプリミティブを導入 – メモリ上に木を構築するプリミティブを導入 – メモリ上の木へのパターンマッチを導入 • 型システム – “何度も使える木” の型 (MTree) を導入 – 入力木スキップ, MTreeに関する規則を導入 – 型判定と変換アルゴリズムを融合 • 変換に型情報を利用するので ターゲット言語への変更 e (項) ::= i | x | λx.e | () | e1 e2 | e1 + e2 | fix f. e | leaf | node | read e | write e | skip e | memtree e | (case e of leaf → e1 | node → e2) | (mcase e of leaf x → e1 | node x1 x2 → e2) 型の拡張 τ (型) ::= Int | τ1 → τ2 | Treed | MTree d (モード) ::= - (入力) | + (出力) 新しい型判定 • 型判定にプログラム変換を含めて書く – 変換に型情報が必要になるので Γ|Δ├M:τe M 中の自由変数が型環境 Γ, Δ に従った型の値に 束縛されるとき, M の評価結果は型τの値となり, 評価中に Δ の順で入力木がアクセスされ, M を変換すると ターゲット言語の項 e になる 型判定規則への変更 (一部のみ) Γ, x:MTree | Δ ├ M :τ e (T-MEMTREE) Γ | x:Tree-, Δ ├ M :τ let x = memtree () in e Γ|Δ├M:τe (T-SKIP) Γ | x:Tree-, Δ├ M : τ let x = skip () in e 発表の流れ • • • • • • 対象言語の syntax 型システム 変換アルゴリズムとその正しさ 拡張に向けて 関連研究 まとめ 関連研究 • 属性文法を用いたXMLストリーム処理器の 自動導出(中野 ’03) – 長所: ストリームの一部をメモリに確保できる – 短所: 副作用を伴う処理の記述が難しい • XMLストリーム処理のための言語XP++ (戸沢,萩谷 ’03) – 長所: 型検査に基づいたノード補完 – 短所: ストリーム処理を意識するが必要 関連研究 • Ordered Linear Logic and applications. (Polakow ’01) • A type theory for memory allocation and data layout. (Petersen et al. ’03) – メモリ上のデータ配置の正しさを保証 まとめ • 二分木を扱う木構造処理プログラムを ストリーム処理プログラムへ変換する手法を 提案 • 変換可能かを判定するため、順序付き線形 型を用いた型システムを考案 • 変換の正しさを証明 Fin 例) 要素全てに1を足した木を作る 関数 • 木構造処理 – let rec f t = match t with Leaf x → Leaf (x + 1) | Node x1 x2 → Node (f x1) (f x2) • ストリーム処理 – let rec f () = match read () of Leaf → write Leaf; write (read() + 1) | Node → write Node; f (); f () 型判定規則への変更 (一部のみ) Γ, x:MTree | Δ ├ M :τ e (T-MEMTREE) Γ | x:Tree-, Δ ├ M :τ let x = memtree () in e Γ | Δ1├ M : MTree e Γ, x:Int | Δ2├ M1:τ e1 Γ, x1:MTree, x2:MTree | Δ2 ├ M2 :τ e2 (T-MCASE) Γ | Δ1, Δ2├ case M of leaf x → M1 | node x1 x2 → M2 :τ mcase e of leaf x → e1 | node x1 x2 → e2
© Copyright 2024 ExpyDoc