26
二二二二二二二 AATT 二二二二二二二二二二二 2010 二 12 二 4 二 二二二二二二

二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

  • View
    229

  • Download
    9

Embed Size (px)

Citation preview

Page 1: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

二分木操作言語 AATT

メタプログラミングの会2010 年 12 月 4 日

郵便はみがき

Page 2: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

自己紹介郵便はみがき• y-hamigaki( はてな ) yhamigaki(Twitter)• ブログ「かそくそうち」

http://d.hatena.ne.jp/y-hamigaki/• フリーソフト「 Dante98 for Windows」• ライブラリ「 Hamigaki C++ Libraries」

2

Page 3: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

• ループや孤島がなくノード間の辺が1本根

ノード

Page 4: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

二分木• 子の数が高々2個

Page 5: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

二分探索木• 小さい値を左の部分木に大きい値を右に

2

1 4

3 5

Page 6: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

平衡二分探索木• 木の偏りを自動的に補正

2

1 4

3 52

1

4

3

5

Page 7: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

赤黒木• 根と空ノードは黒• 赤ノードの子は黒ノード• 根から葉までの黒ノードの数が同じ

2

1 4

3 50

Page 8: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

赤黒木への挿入• 赤ノードとして追加• 赤黒木の制約を満たさない場合は変形

1

3

20

2

0

31右回転

Page 9: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

パターンマッチなら簡単?• Togetter 「 kinaba さんが Cryolite を洗脳

してパターンマッチ厨に仕立て上げるリスト」

AA がないと読めません!

balance :: RB a -> a -> RB a -> RB abalance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d)balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)balance a x b = T B a x b

http://www.cs.kent.ac.uk/people/staff/smk/redblack/Untyped.hs

Page 10: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

ASCII Art Tree Transform(AATT)

• 英小文字→赤ノード、英小文字→黒ノード

• 数字→赤ノードか黒ノード• 「 ^ 」が探索位置、「 * 」がルート*

G P

/ ∖ / ∖

p U — > n g

/ ∖ / ∖

n 3 3 U

^

Page 11: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

AATT のパターンマッチ• 上から順にパターンマッチを行う• 変形後の木に「 ^ 」があれば再帰

G P

/ ∖ / ∖

p U — > n g

/ ∖ / ∖

n 3 3 U

^

G P

/ ∖ / ∖

U p p — > g n

/ ∖ / ∖

3 3 n U 3

^

Page 12: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

AATT のパース 1

• 空行でパターンを分離G P

/ ∖ / ∖

p U — > n g

/ ∖ / ∖

n 3 3 U

^

G P

/ ∖ / ∖

U p p — > g n

/ ∖ / ∖

3 3 n U 3

^

Page 13: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

AATT のパース 2

• 「 -> 」で入力と出力を分離

G P

/ ∖ / ∖

p U — > n g

/ ∖ / ∖

n 3 3 U

^

Page 14: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

AATT のパース 3

• 「 ^ 」からノードを探索して配列に記録

この順にノードをチェックする

G

/ ∖

p U

/ ∖

n 3

^

名前 親 左 右 種別

N P nil nil 起点

P G N 3 右親

3 P nil nil 右子

G nil P U 右親

U G nil nil 右子

Page 15: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

AATT の変形• 表を見比べて違うリンクとカラーを書き

換える名前 親 左 右 種別

N P nil nil 起点

P G N 3 右親

3 P nil nil 右子

G nil P U 右親

U G nil nil 右子

名前 親 左 右 種別

N P nil nil 左子

P nil N G 起点

3 G nil nil 左子

G P 3 U 右子

U G nil nil 右子

Page 16: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

AATT 出力例inline tree_node* balance(tree_node* root, tree_node* node){ tree_node* pN = node; if ((pN != 0) && (pN->color == RED)){ tree_node* pP = pN->parent; if ((pP != 0) && (pP->left == pN) && (pP->color == RED)){ tree_node* pG = pP->parent; if ((pG != 0) && (pG->left == pP) && (pG->color == BLACK)){ tree_node* pU = pG->right; if ((pU != 0) && (pU->color == RED)){ pG->color = RED; pP->color = BLACK; pU->color = BLACK; return balance(root, pG);

Page 17: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

D 言語への移植• WYSIWYG 文字列で D ソースコードに埋め

込み• テンプレート実引数に設定• D 言語のソースコードを出力する関数を作

成• mixin 文でコンパイル時に評価 (CTFE)• dmd 2.050 で確認

Page 18: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

D 版 AATT の問題点 1

• mixin コード片中で再帰呼び出しが出来ない{ TreeNode!(T)* pN = node; // ...}{ TreeNode!(T)* pN = node; if (…) { if (TreeNode!(T)* pP = pN.parent) { node = pP; // ここで自分自身を呼びたい

Page 19: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

goto

• 末尾再帰なので goto 文で解決loop:{ TreeNode!(T)* pN = node; // ...}{ TreeNode!(T)* pN = node; if (…) { if (TreeNode!(T)* pP = pN.parent) { node = pP; goto loop;

Page 20: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

goto 文の制約• 同名の変数定義があると goto できない

loop:{ TreeNode!(T)* pN = node; // ...}{ TreeNode!(T)* pN = node; if (…) { if (TreeNode!(T)* pP = pN.parent) { node = pP; goto loop;

Page 21: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

変数名に序数を付ける• コード生成関数にシーケンスを渡して別名

にloop:{ TreeNode!(T)* pN0 = node; // ...}{ TreeNode!(T)* pN1 = node; if (…) { if (TreeNode!(T)* pP = pN1.parent) { node = pP; goto loop;

Page 22: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

D 版 AATT の問題点 2

• CTFE で再帰呼び出しが出来ないchar parseTree( ref AA_TreeNode[] tree, AsciiArtRect aa, AA_TreeNode.Types type, char from, size_t y, size_t x){ // ... node.parent = parseTree( tree, aa, AA_TreeNode.Types.RIGHT_PARENT, c, pos.y, pos.x );

Page 23: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

再帰だけど再帰じゃない• 再帰の深度毎に別の関数にしてみる

char parseTree(int depth)( ref AA_TreeNode[] tree, AsciiArtRect aa, AA_TreeNode.Types type, char from, size_t y, size_t x){ // ... node.parent = parseTree!(depth+1)( tree, aa, AA_TreeNode.Types.RIGHT_PARENT, c, pos.y, pos.x );

Page 24: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

番兵• ノードは英字 26 文字 + 数字 10 文字のみ• 文法上再帰の深度は 35 が最大• 36 段目は空ノードしかありえない

char parseTree(int depth: 36)( ref AA_TreeNode[] tree, AsciiArtRect aa, AA_TreeNode.Types type, char from, size_t y, size_t x){ return AA_TreeNode.NIL;}

Page 25: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

使用例TreeNode!(T)* balance3a(T)(TreeNode!(T)* root, TreeNode!(T)* node){ return aatt.transform!(T,r" G g / /^ ∖ ∖ p u -> P U / / n n ^")(root, node);}

Page 26: 二分木操作言語 AATT メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介 郵便はみがき y-hamigaki( はてな ) yhamigaki(Twitter) y-hamigakiyhamigaki

まとめ• AA で書いたツリー操作がそのままコード

に• C++ と D(D2) に対応• D へのトランスレータさえ書けば CTFE で

きる• D は不思議言語• 次のバージョンでは動かないかも