Mercurial > hg > Members > soto > experimental
view bt.agda @ 4:fb1b3d066f63
WIP continuation insert at LLRB-Tree
author | soto |
---|---|
date | Sat, 21 Nov 2020 14:50:05 +0900 |
parents | c0bcdd0552f1 |
children | 5b56077a1862 |
line wrap: on
line source
module bt where open import Data.Nat hiding (compare) open import Data.Nat.Properties as NatProp -- <-cmp open import Relation.Binary open import Data.List data col : Set where black : col red : col record node (A B : Set) : Set where field coler : A number : B record tree (A B C : Set) : Set where field key : A ltree : B rtree : C data bst : Set where bt-empty : bst bt-node : (node : tree (node col ℕ) bst bst ) → bst test : bst test = bt-node (record { key = record { coler = red ; number = zero }; ltree = bt-empty; rtree = bt-empty }) -- 右回転 rotate_right : bst → bst rotate_right bt-empty = bt-empty rotate_right node@(bt-node (record { key = _; ltree = bt-empty; rtree = _ }) ) = node rotate_right (bt-node (record { key = record { coler = y ; number = x } ; ltree = (bt-node (record { key = record { coler = ly ; number = lx }; ltree = ll; rtree = lr }) ) ; rtree = r }) ) = (bt-node (record { key = record { coler = y ; number = lx } ; ltree = ll ; rtree = (bt-node (record { key = record { coler = red ; number = x }; ltree = lr; rtree = r }) ) }) ) -- 左回転 rotate_left : bst → bst rotate_left bt-empty = bt-empty rotate_left node@(bt-node (record { key = _; ltree = _; rtree = bt-empty }) ) = node rotate_left (bt-node (record { key = record { coler = y ; number = x } ; ltree = l ; rtree = (bt-node (record { key = record { coler = ry ; number = rx }; ltree = rl; rtree = rr }) ) }) ) = (bt-node (record { key = record { coler = y ; number = rx } ; ltree = (bt-node (record { key = record { coler = red ; number = x }; ltree = l; rtree = rl }) ) ; rtree = rr }) ) -- skew skew : bst → bst skew bt-empty = bt-empty skew node@(bt-node (record { key = _; ltree = _ ; rtree = bt-empty }) ) = node skew node@(bt-node (record { key = record { coler = y ; number = x } ; ltree = l ; rtree = (bt-node (record { key = record { coler = red ; number = lx }; ltree = ll; rtree = lr }) )}) ) = rotate_left node skew node@(bt-node (record { key = record { coler = y ; number = x } ; ltree = l ; rtree = (bt-node (record { key = record { coler = black ; number = lx }; ltree = ll; rtree = lr }) ) }) ) = node split : bst → bst split bt-empty = bt-empty split node@(bt-node (record { key = record { coler = y ; number = x }; ltree = l; rtree = bt-empty }) ) = node split node@(bt-node (record { key = record { coler = y ; number = x }; ltree = bt-empty; rtree = r }) ) = node split node@(bt-node (record { key = record { coler = y ; number = x } ; ltree = (bt-node (record { key = record { coler = ly ; number = lx }; ltree = ll; rtree = lr }) ) ; rtree = (bt-node (record { key = record { coler = ry ; number = rx }; ltree = rl; rtree = rr }) )}) ) = bt-node (record { key = record { coler = red ; number = x } ; ltree = (bt-node (record { key = record { coler = black ; number = lx }; ltree = ll; rtree = lr }) ) ; rtree = (bt-node (record { key = record { coler = black ; number = rx }; ltree = rl; rtree = rr }) )}) -- split split_branch : bst → bst split_branch bt-empty = bt-empty split_branch node@(bt-node (record { key = _; ltree = bt-empty; rtree = _}) ) = node split_branch node@(bt-node (record { key = record { coler = y ; number = x } ; ltree = (bt-node (record { key = record { coler = red ; number = rx } ; ltree = (bt-node (record { key = record { coler = red ; number = rrx }; ltree = rrl; rtree = rrr }) ) ; rtree = lr })) ; rtree = r }) ) = split (rotate_right node) split_branch node@(bt-node (record { key = record { coler = y ; number = x } ; ltree = (bt-node (record { key = record { coler = red ; number = rx } ; ltree = (bt-node (record { key = record { coler = black ; number = rrx }; ltree = lll; rtree = rrr })) ; rtree = lr }) ) ; rtree = r }) ) = node split_branch node@(bt-node (record { key = record { coler = y ; number = x } ; ltree = (bt-node (record { key = record { coler = red ; number = rx } ; ltree = bt-empty ; rtree = rr }) ) ; rtree = r}) ) = node split_branch node@(bt-node (record { key = record { coler = y ; number = x } ; ltree = (bt-node (record { key = record { coler = black ; number = rx }; ltree = rl; rtree = rr }) ) ; rtree = r }) ) = node insert_pipeline : bst → bst insert_pipeline node = split_branch (skew node) -- insert bt-insert : bst → ℕ → bst bt-insert bt-empty n = ( bt-node (record { key = record { coler = red ; number = n }; ltree = bt-empty; rtree = bt-empty }) ) bt-insert (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n with <-cmp x n bt-insert (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n | tri≈ ¬a b ¬c = (bt-node (record { key = record { coler = y ; number = x }; ltree = l; rtree = r }) ) bt-insert (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n | tri> ¬a ¬b c = (insert_pipeline (bt-node (record { key = record { coler = y ; number = x }; ltree = (bt-insert l n); rtree = r }) ) ) bt-insert (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n | tri< a ¬b ¬c = (insert_pipeline (bt-node (record { key = record { coler = y ; number = x }; ltree = l; rtree = (bt-insert r n) }) ) ) init_node_coler : bst → bst init_node_coler bt-empty = bt-empty init_node_coler (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) = (bt-node (record { key = record { coler = black; number = x }; ltree = l; rtree = r }) ) insert : bst → ℕ → bst insert node x = init_node_coler (bt-insert node x) -- 赤黒木のinsertをする rbt-insert2 : bst → ℕ → List bst → bst rbt-insert2 bt-empty n stack = ( bt-node (record { key = record { coler = red ; number = n }; ltree = bt-empty; rtree = bt-empty }) ) rbt-insert2 (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n stack with <-cmp x n rbt-insert2 (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n stack | tri≈ ¬a b ¬c = (bt-node (record { key = record { coler = y ; number = x }; ltree = l; rtree = r }) ) rbt-insert2 (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n stack | tri> ¬a ¬b c = (insert_pipeline (bt-node (record { key = record { coler = y ; number = x }; ltree = (rbt-insert2 l n stack); rtree = r }) ) ) rbt-insert2 (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n stack | tri< a ¬b ¬c = (insert_pipeline (bt-node (record { key = record { coler = y ; number = x }; ltree = l; rtree = (rbt-insert2 r n stack) }) ) ) --treeをmerge merge-tree : bst → List bst → bst merge-tree node [] = init_node_coler (insert_pipeline node) merge-tree x (bt-empty ∷ xs) = bt-empty merge-tree bt-empty s = bt-empty merge-tree target@(bt-node (record { key = record { coler = ty; number = tx }; ltree = tl; rtree = tr }) ) ( (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) ∷ xs) with <-cmp tx x merge-tree target@(bt-node (record { key = record { coler = ty; number = tx }; ltree = tl; rtree = tr }) ) ( (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) ∷ xs) | tri≈ ¬a b ¬c = merge-tree ( insert_pipeline (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r } ) ) ) xs -- merge-tree (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r } ) ) xs merge-tree target@(bt-node (record { key = record { coler = ty; number = tx }; ltree = tl; rtree = tr }) ) ( (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) ∷ xs) | tri> ¬a ¬b c = merge-tree ( insert_pipeline (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = target } ) ) ) xs -- merge-tree (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = target } ) ) xs merge-tree target@(bt-node (record { key = record { coler = ty; number = tx }; ltree = tl; rtree = tr }) ) ( (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) ∷ xs) | tri< a ¬b ¬c = merge-tree ( insert_pipeline (bt-node (record { key = record { coler = y; number = x }; ltree = target; rtree = r } ) ) ) xs -- merge-tree (bt-node (record { key = record { coler = y; number = x }; ltree = target; rtree = r } ) ) xs --(bt-node (record { key = record { coler = red ; number = 1 }; ltree = bt-empty; rtree = bt-empty })) -- merge-tree node ( (bt-node (record { key = record { coler = y; number = x }; ltree = bt-empty; rtree = bt-node r }) ) ∷ xs) = merge-tree (bt-node (record { key = record { coler = y; number = x }; ltree = node ; rtree = bt-node r }) ) xs -- merge-tree node ( (bt-node (record { key = record { coler = y; number = x }; ltree = bt-node l; rtree = bt-empty }) ) ∷ xs) = merge-tree (bt-node (record { key = record { coler = y; number = x }; ltree = bt-node l ; rtree = node }) ) xs --merge-tree node ( (bt-node (record { key = record { coler = y; number = x }; ltree = bt-node _; rtree = bt-node _ }) ) ∷ xs) = bt-empty rbt-insert : bst → ℕ → List bst → bst rbt-insert bt-empty n stack = merge-tree (bt-node (record { key = record { coler = red ; number = n }; ltree = bt-empty; rtree = bt-empty }) ) stack -- ( bt-node (record { key = record { coler = red ; number = n }; ltree = bt-empty; rtree = bt-empty }) ) -- mergeに遷移する rbt-insert (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n stack with <-cmp x n rbt-insert (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n stack | tri≈ ¬a b ¬c = (bt-node (record { key = record { coler = y ; number = x }; ltree = l; rtree = r }) ) rbt-insert (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n stack | tri> ¬a ¬b c = rbt-insert l n ( (bt-node (record { key = record { coler = y ; number = x }; ltree = bt-empty; rtree = r }) ) ∷ stack) rbt-insert (bt-node (record { key = record { coler = y; number = x }; ltree = l; rtree = r }) ) n stack | tri< a ¬b ¬c = rbt-insert r n ( (bt-node (record { key = record { coler = y ; number = x }; ltree = l; rtree = bt-empty }) ) ∷ stack ) -- 以下test部分 test-rbt1 = rbt-insert bt-empty 0 [] test-rbt2 = rbt-insert test-rbt1 1 [] test-rbt3 = rbt-insert test-rbt2 2 [] test-rbt4 = rbt-insert test-rbt3 3 [] test-rbt5 = rbt-insert test-rbt4 4 [] test-rbt6 = rbt-insert test-rbt5 5 [] test-insert1 : bst test-insert1 = insert bt-empty 0 test-insert2 : bst test-insert2 = insert test-insert1 1 test-insert3 : bst test-insert3 = insert test-insert2 2 test-insert4 : bst test-insert4 = insert test-insert3 3 test-insert5 : bst test-insert5 = insert test-insert4 4 test-insert6 : bst test-insert6 = insert test-insert5 5 test-insert7 : bst test-insert7 = insert test-insert6 6