slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
二分木操作言語 AATT PowerPoint Presentation
Download Presentation
二分木操作言語 AATT

Loading in 2 Seconds...

play fullscreen
1 / 26

二分木操作言語 AATT - PowerPoint PPT Presentation


  • 82 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1

二分木操作言語AATT

メタプログラミングの会

2010年12月4日

郵便はみがき

slide2
自己紹介

郵便はみがき

  • y-hamigaki(はてな)yhamigaki(Twitter)
  • ブログ「かそくそうち」

http://d.hatena.ne.jp/y-hamigaki/

  • フリーソフト「Dante98 for Windows」
  • ライブラリ「Hamigaki C++ Libraries」
slide3
  • ループや孤島がなくノード間の辺が1本

ノード

slide4
二分木
  • 子の数が高々2個
slide5
二分探索木
  • 小さい値を左の部分木に大きい値を右に

2

1

4

3

5

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

5

2

4

1

3

4

2

3

5

1

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

2

1

4

0

3

5

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

1

2

右回転

2

0

3

1

3

0

slide9
パターンマッチなら簡単?
  • 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

ascii art tree transform aatt
ASCII Art Tree Transform(AATT)
  • 英小文字→赤ノード、英小文字→黒ノード
  • 数字→赤ノードか黒ノード
  • 「^」が探索位置、「*」がルート
slide11
AATTのパターンマッチ
  • 上から順にパターンマッチを行う
  • 変形後の木に「^」があれば再帰
aatt 1
AATTのパース1
  • 空行でパターンを分離
aatt 2
AATTのパース2
  • 「->」で入力と出力を分離
aatt 3
AATTのパース3
  • 「^」からノードを探索して配列に記録

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

slide15
AATTの変形
  • 表を見比べて違うリンクとカラーを書き換える
slide16
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);

slide17
D言語への移植
  • WYSIWYG文字列でDソースコードに埋め込み
  • テンプレート実引数に設定
  • D言語のソースコードを出力する関数を作成
  • mixin文でコンパイル時に評価(CTFE)
  • dmd 2.050 で確認
d aatt 1
D版AATTの問題点1
  • mixinコード片中で再帰呼び出しが出来ない

{

TreeNode!(T)* pN = node;

// ...

}

{

TreeNode!(T)* pN = node;

if (…) {

if (TreeNode!(T)* pP = pN.parent) {

node = pP;

// ここで自分自身を呼びたい

slide19
goto
  • 末尾再帰なのでgoto文で解決

loop:

{

TreeNode!(T)* pN = node;

// ...

}

{

TreeNode!(T)* pN = node;

if (…) {

if (TreeNode!(T)* pP = pN.parent) {

node = pP;

goto loop;

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

loop:

{

TreeNode!(T)* pN = node;

// ...

}

{

TreeNode!(T)* pN = node;

if (…) {

if (TreeNode!(T)* pP = pN.parent) {

node = pP;

goto loop;

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

loop:

{

TreeNode!(T)* pN0 = node;

// ...

}

{

TreeNode!(T)* pN1 = node;

if (…) {

if (TreeNode!(T)* pP = pN1.parent) {

node = pP;

goto loop;

d aatt 2
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

);

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

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

);

slide24
番兵
  • ノードは英字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;

}

slide25
使用例

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

}

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