1 / 26

二分木操作言語 AATT

二分木操作言語 AATT. メタプログラミングの会 2010 年 12 月 4 日 郵便はみがき. 自己紹介. 郵便はみがき y-hamigaki ( はてな ) yhamigaki (Twitter) ブログ「かそくそうち」 http://d.hatena.ne.jp/y-hamigaki/ フリーソフト 「 Dante98 for Windows 」 ライブラリ「 Hamigaki C++ Libraries 」. 木. ループや孤島がなくノード間の辺が1本. 根. 辺. ノード. 葉. 二分木. 子 の 数が高々2個. 二分探索木.

damia
Download Presentation

二分木操作言語 AATT

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 二分木操作言語AATT メタプログラミングの会 2010年12月4日 郵便はみがき

  2. 自己紹介 郵便はみがき • y-hamigaki(はてな)yhamigaki(Twitter) • ブログ「かそくそうち」 http://d.hatena.ne.jp/y-hamigaki/ • フリーソフト「Dante98 for Windows」 • ライブラリ「Hamigaki C++ Libraries」

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

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

  5. 二分探索木 • 小さい値を左の部分木に大きい値を右に 2 1 4 3 5

  6. 平衡二分探索木 • 木の偏りを自動的に補正 5 2 4 1 3 4 2 3 5 1

  7. 赤黒木 • 根と空ノードは黒 • 赤ノードの子は黒ノード • 根から葉までの黒ノードの数が同じ 2 1 4 0 3 5

  8. 赤黒木への挿入 • 赤ノードとして追加 • 赤黒木の制約を満たさない場合は変形 1 2 右回転 2 0 3 1 3 0

  9. パターンマッチなら簡単? • Togetter「kinabaさんが Cryoliteを洗脳してパターンマッチ厨に仕立て上げるリスト」 AAがないと読めません! http://www.cs.kent.ac.uk/people/staff/smk/redblack/Untyped.hs balance :: RB a -> a -> RB a -> RB a balance (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

  10. ASCII Art Tree Transform(AATT) • 英小文字→赤ノード、英小文字→黒ノード • 数字→赤ノードか黒ノード • 「^」が探索位置、「*」がルート

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

  12. AATTのパース1 • 空行でパターンを分離

  13. AATTのパース2 • 「->」で入力と出力を分離

  14. AATTのパース3 • 「^」からノードを探索して配列に記録 この順にノードをチェックする

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

  16. 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);

  17. D言語への移植 • WYSIWYG文字列でDソースコードに埋め込み • テンプレート実引数に設定 • D言語のソースコードを出力する関数を作成 • mixin文でコンパイル時に評価(CTFE) • dmd 2.050 で確認

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

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

  20. goto文の制約 • 同名の変数定義があるとgotoできない loop: { TreeNode!(T)* pN = node; // ... } { TreeNode!(T)* pN = node; if (…) { if (TreeNode!(T)* pP = pN.parent) { node = pP; goto loop;

  21. 変数名に序数を付ける • コード生成関数にシーケンスを渡して別名に loop: { TreeNode!(T)* pN0 = node; // ... } { TreeNode!(T)* pN1 = node; if (…) { if (TreeNode!(T)* pP = pN1.parent) { node = pP; goto loop;

  22. D版AATTの問題点2 • CTFEで再帰呼び出しが出来ない char parseTree( ref AA_TreeNode[] tree, AsciiArtRectaa, 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 );

  23. 再帰だけど再帰じゃない • 再帰の深度毎に別の関数にしてみる char parseTree(int depth)( ref AA_TreeNode[] tree, AsciiArtRectaa, 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 );

  24. 番兵 • ノードは英字26文字+数字10文字のみ • 文法上再帰の深度は35が最大 • 36段目は空ノードしかありえない char parseTree(int depth: 36)( ref AA_TreeNode[] tree, AsciiArtRectaa, AA_TreeNode.Types type, char from, size_t y, size_t x) { return AA_TreeNode.NIL; }

  25. 使用例 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); }

  26. まとめ • AAで書いたツリー操作がそのままコードに • C++とD(D2)に対応 • Dへのトランスレータさえ書けばCTFEできる • Dは不思議言語 • 次のバージョンでは動かないかも

More Related