AVL Trees D Oisín Kidne August 2, 2018 Astrt This is verified implementtion of AVL trees in Agd, tking ides primril from Conor MBride s pper How to Keep Your Neighours in Order [2] nd the Agd stndrd lirr [1]. Contents 1 Introdution 2 2 Bounded 2 3 Blne 3 4 The Tree Tpe 3 5 Rottions 4 5.1 Right Rottion......................... 5 5.2 Left Rottion.......................... 5 6 Insertion 6 7 Lookup 7 8 Deletion 7 8.1 Unons............................. 8 8.2 Widening nd Trnsitivit.................. 8 8.3 Joining............................. 9 8.4 Full Deletion.......................... 9 9 Altertion 10 10 Pkging 12 10.1 Dependent Mp........................ 12 10.2 Non-Dependent (Simple) Mp................ 13 10.3 Set................................ 14 1
1 Introdution First, some imports. {-# OPTIONS --without-k #-} open import Reltion.Binr open import Reltion.Binr.PropositionlEqulit open import Level using (Lift; lift; _ _; lower) open import Dt.Nt s N using (N; su; zero; pred) open import Dt.Produt open import Dt.Unit open import Dt.Me open import Funtion open import Dt.Bool open import Dt.Empt Net, we delre module: the entiret of the following ode is prmeterized over the ke tpe, nd strit totl order on tht ke. module AVL {k r} (Ke : Set k) {_<_ : Rel Ke r} (isstrittotlorder : IsStritTotlOrder _ <_) where open IsStritTotlOrder isstrittotlorder 2 Bounded The si ide of the verified implementtion is to store in eh lef proof tht the upper nd lower ounds of the trees to its left nd right re ordered ppropritel. Aordingl, the tree tpe itself will hve to hve the upper nd lower ounds in its indies. But wht re the upper nd lower ounds of tree with no neighours? To desrie this se, we dd lower nd upper ounds to our ke tpe. module Bounded where infi 5 [_] dt [ ] : Set k where : [ ] [_] : (k : Ke) [ ] This tpe itself dmits n ordering reltion. infi 4 _[<] [<]_ : [ ] [ ] Set r 2
[<] = Lift r [<] = Lift r [<] [ _ ] = Lift r [<] _ = Lift r [ _ ] [<] = Lift r [ _ ] [<] = Lift r [ ] [<] [ ] = < Finll, we n desrie vlue s eing in ounds like so. infi 4 _<_< <_<_ : [ ] Ke [ ] Set r l < < u = l [<] [ ] [ ] [<] u 3 Blne To desrie the lne of the tree, we use the following tpe: dt _ _ _ : N N N Set where : {n} su n n su n : {n} n n n : {n} n su n su n The tree n e either left- or right-hev ( one), or even. The indies of the tpe re phrsed s proof: m(, ) = z (1) The height of tree is the mimum height of its two sutrees, plus one. Storing proof of the mimum in this w will prove useful lter. We will lso need some omintors for lne: : { z} z z z = = = : { z} z z z = = = 4 The Tree Tpe The tpe itself is indeed the lower nd upper ounds, some vlue to store with the kes, nd height. In using the lne tpe defined erlier, we ensure tht the hildren of node nnot differ in height 3
more thn 1. The ounds proofs lso ensure tht the tree must e ordered orretl. dt Tree {v} (V : Ke Set v) (l u : [ ]) : N Set (k v r) where lef : (l<u : l [<] u) Tree V l u 0 node : {h lh rh} (k : Ke) (v : V k) (l : lh rh h) (lk : Tree V l [ k ] lh) (ku : Tree V [ k ] u rh) Tree V l u (su h) 5 Rottions AVL trees re relned rottions: if, fter n insert or deletion, the lne invrint hs een violted, one of these rottions is performed s orretion. Before we implement the rottions, we need w to desrie tree whih m hve inresed in height. We n do this with desriptive tpe: _1?+ _ : {l} (T : N Set l) N Set l T 1?+ n = [ in? ] T (if in? then su n else n) pttern 0+_ tr = flse, tr pttern 1+_ tr = true, tr Lter, we will lso need to desrie tree whih m hve deresed in height. For this, we will use presriptive tpe (in other words, where the previous tpe ws prmeterized, this one will e indeed). dt _ _? 1 {l} (T : N Set l) : N Set l where _ 0 : {n} T n T n? 1 _ 1 : {n} T n T su n? 1 Wheres the previous onstrution would tell ou the height of tree fter pttern mthing on it, this definition will refine n informtion ou lred hve out the height of the tree. In ertin irumstnes, ou n onvert etween the two: 1?+ _? 1 : {n l} {T : N Set l} T 1?+ n T su n? 1 1?+ 0+? 1 = 1 1?+ 1+? 1 = 0 4
5.1 Right Rottion When the left sutree eomes too hev, we rotte the tree to the right. rot r : {l u rh v} {V : Ke Set v} (k : Ke) V k Tree V l [ k ] (su (su rh)) Tree V [ k ] u rh Tree V l u 1?+ su (su rh) This rottion omes in two vrieties: single nd doule. Single rottion n e seen in figure 1. Figure 1: Single right-rottion rot r v (node v ) = 0+ (node v (node v rot r v (node v ) = 1+ (node v (node v )) )) And doule rottion in figure 2. d z z d Figure 2: Doule right-rottion rot r v (node v (node z zv l )) d = 0+ (node z zv (node v ( l) ) (node v ( l) d)) 5.2 Left Rottion Left-rottion is essentill the inverse of right. 5
rot l : {l u lh v} {V : Ke Set v} (k : Ke) V k Tree V l [ k ] lh Tree V [ k ] u (su (su lh)) Tree V l u 1?+ su (su lh) Single (seen in figure 3). Figure 3: Single left-rottion rot l v (node v ) = 0+ (node v (node v ) ) rot l v (node v ) = 1+ (node v (node v nd doule (figure 4): ) ) d z z d Figure 4: Doule left-rottion rot l v d (node v (node z zv l ) ) = 0+ (node z zv (node v ( l) d ) (node v ( l) )) 6 Insertion After the rottions, insertion is reltivel es. suppl omining funtion. We llow the ller to insert : {l u h v} {V : Ke Set v} (k : Ke) V k 6
(V k V k V k) Tree V l u h l < k < u Tree V l u 1?+ h insert v v f (lef l<u) (l, u) = 1+ (node v v (lef l) (lef u)) insert v v f (node k k l tl tr) prf with ompre v k insert v v f (node k k l tl tr) (l, _) tri< with insert v v f tl (l, )... 0+ tl = 0+ (node k k l tl tr)... 1+ tl with l... = rot r k k tl tr... = 1+ (node k k tl tr)... = 0+ (node k k tl tr) insert v v f (node k k l tl tr) _ tri _ refl _ = 0+ (node k (f v k) l tl tr) insert v v f (node k k l tl tr) (_, u) tri> with insert v v f tr (, u)... 0+ tr = 0+ (node k k l tl tr )... 1+ tr with l... = 0+ (node k k tl tr )... = 1+ (node k k tl tr )... = rot l k k tl tr 7 Lookup Lookup is lso ver simple. No invrints re needed here. lookup : (k : Ke) {l u s v} {V : Ke Set v} Tree V l u s Me (V k) lookup k (lef l<u) = nothing lookup k (node v v _ tl tr) with ompre k v... tri< _ = lookup k tl... tri _ refl _ = just v... tri> _ = lookup k tr 8 Deletion Deletion is fr the most omple opertion out of the three provided here. For deletion from norml BST, ou go to the node where the desired vlue is, perform n unons opertion on the right sutree, use tht s our root node, nd merge the two remining hildren. 7
8.1 Unons First then, we need to define unons. We ll use ustom tpe s the return tpe from our unons funtion, whih stores the minimum element from the tree, nd the rest of the tree: reord Cons {v} (V : Ke Set v) (l u : [ ]) (h : N) : Set (k v r) where onstrutor ons field hed : Ke vl : V hed l<u : l [<] [ hed ] til : Tree V [ hed ] u 1?+ h You ll notie it lso stores proof tht the etrted element preserves the lower ound. unons : {l u h lh rh v} {V : Ke Set v} (k : Ke) V k lh rh h Tree V l [ k ] lh Tree V [ k ] u rh Cons V l u h unons k v (lef l<u) tr = ons k v l<u (se of ń { 0+ tr ; 0+ tr }) unons k v (node k l v l l tl l tr l ) tr with unons k l v l l tl l tr l... ons k v l<u til = ons k v l<u (se til of ń { (1+ tl ) 1+ (node k v tl tr) ; (0+ tl ) se of ń { 0+ node k v tl tr ; 1+ node k v tl tr ; rot l k v tl tr }}) 8.2 Widening nd Trnsitivit To join the two sutrees together fter deletion opertion, we need to weken (or et) the ounds of the left tree. This is n O(log n) opertion. For the eting, we ll need some properties on orderings: : {} [<] Lift r { } = lift lower { } = lift lower {[ _ ]} = lift lower [<]-trns : { z} [<] [<] z [<] z 8
[<]-trns {} { } _ <z = { = } <z [<]-trns {_} { } = _ [<]-trns {_} {[ _ ]} = _ [<]-trns {_} {_} (lift ()) _ [<]-trns [ _ ] {} { } _ <z = { = } <z [<]-trns [ _ ] {_} { } = _ [<]-trns [ _ ] { } {[ _ ]} (lift ()) _ [<]-trns [ _ ] { } {[ _ ]} _ (lift ()) [<]-trns [ ] {[ ]} {[ z ]} < <z = IsStritTotlOrder.trns isstrittotlorder < <z Finll, the et funtion itself simpl wlks down the right rnh of the tree until it hits lef. et : {l u u h v} {V : Ke Set v} u [<] u Tree V l u h Tree V l u h et {l} u<u (lef l<u) = lef ([<]-trns l l<u u<u ) et u<u (node k v l tl tr) = node k v l tl (et u<u tr) 8.3 Joining One we hve the two sutrees tht will form the hildren of our repled node, we need to join them together, djusting the tpes ordingl. join : {l u lh rh h v k} {V : Ke Set v} Tree V [ k ] u rh lh rh h Tree V l [ k ] lh Tree V l u 1?+ h join (lef k<u) tl = 0+ et k<u tl join {l} (lef k<u) (lef l<k) = 0+ lef ([<]-trns l l<k k<u) join (node k r v r r tl r tr r ) tl with unons k r v r r tl r tr r... ons k v l<u (1+ tr ) = 1+ node k v (et l<u tl) tr... ons k v l<u (0+ tr ) with... = rot r k v (et l<u tl) tr... = 1+ node k v (et l<u tl) tr... = 0+ node k v (et l<u tl) tr 8.4 Full Deletion The deletion funtion is no mens simple, ut it does mintin the orret ompleit ounds. delete : {l u h v} {V : Ke Set v} (k : Ke) 9
Tree V l u h Tree V l u h? 1 delete (lef l<u) = lef l<u 0 delete (node v l r) with ompre delete (node. v l r) tri _ refl _ = 1?+ join r l? 1 delete (node v l r) tri< with delete l... l 0 = node v l r 0... l 1 with... = node v l r 1... = node v l r 0... = 1?+ rot l v l r? 1 delete (node v l r) tri> with delete r... r 0 = node v l r 0... r 1 with... = 1?+ rot r v l r? 1... = node v l r 0... = node v l r 1 9 Altertion This is omintion of insertion nd deletion: it lets the user suppl funtion to modif, insert, or remove n element, depending on the element lred in the tree. As it n oth inrese nd derese the size of the tree, we need wrpper to represent tht: dt _ _ ±1 {l} (T : N Set l) : N Set l where 1+ _ : {n} T (su n) T n ±1 _ : {n} T n T n ±1 _ 1 : {n} T n T su n ±1 1?+ _ 1 : {n l} {T : N Set l} T 1?+ n T su n ±1 1?+ 0+ 1 = 1 1?+ 1+ 1 = 1?+ _ +1 : {n l} {T : N Set l} T 1?+ n T n ±1 1?+ 0+ +1 = 1?+ 1+ +1 = 1+ And then the funtion itself. It s long, ut ou should e le to see the deletion nd insertion omponents. lter : {l u h v} {V : Ke Set v} (k : Ke) 10
(Me (V k) Me (V k)) Tree V l u h l < k < u Tree V l u h ±1 lter f (lef l<u) (l, u) with f nothing... just v = 1+ node v (lef l) (lef u)... nothing = lef l<u lter f (node v tl tr) (l, u) with ompre lter f (node. v tl tr) (l, u) tri _ refl _ with f (just v)... just v = node v tl tr... nothing = 1?+ join tr tl 1 lter f (node v tl tr) (l, u) tri< with lter f tl (l, )... tl _ = node v tl tr... 1+ tl = 1?+ rot r v tl tr +1... 1+ tl = 1+ node v tl tr... 1+ tl = node v tl tr... tl 1 = node v tl tr 1... tl 1 = node v tl tr... tl 1 = 1?+ rot l v tl tr 1 lter f (node v tl tr) (l, u) tri> with lter f tr (, u)... tr _ = node v tl tr... 1+ tr = node v tl tr... 1+ tr = 1+ node v tl tr... 1+ tr... tr 1... tr 1... tr 1 = 1?+ rot l v tl tr +1 = 1?+ rot r v tl tr 1 = node v tl tr = node v tl tr 1 We n lso write lterf, in the lens stle. open import Ctegor.Funtor using (RwFuntor) MeVl : {v} (V : Set v) Set (k r v) MeVl V = Lift (k r) (Me V) lterf : {l u h v} {V : Ke Set v} ( : Ke) {F : Set (k r v) Set (k r v)} {{funtor : RwFuntor F}} (Me (V ) F (MeVl (V ))) Tree V l u h l < < u F (Tree V l u h ±1) lterf {l} {u} {h} {_} {V} {F} {{funtor}} f root nds = go root nds id 11
where _<&>_ : {A B} F A (A B) F B s <&> f = RwFuntor._<$>_ funtor f s go : {l u h } Tree V l u h l < < u (Tree V l u h ±1 Tree V l u h ±1) F (Tree V l u h ±1) go (lef l<u) (l, u) k = f nothing <&> ń { (lift nothing) root ; (lift (just v)) k 1+ node v (lef l) (lef u) } go (node v tl tr) (l, u) k with ompre go (node. v tl tr) (l, u) k tri _ refl _ = f (just v) <&> ń { (lift nothing) k 1?+ join tr tl 1 ; (lift (just v)) k node v tl tr } go (node v tl tr) (l, u) k tri< = go tl (l, ) (k ń { tl node v tl tr ; 1+ tl se of ń { 1?+ rot r v tl tr +1 ; 1+ node v tl tr node v tl tr } ; tl 1 se of ń { node v tl tr 1 ; node v tl tr ; ; 1?+ rot l v tl tr 1 }}) go (node v tl tr) (l, u) k tri> = go tr (, u) (k ń { tr node v tl tr ; 1+ tr se of ń { node v tl tr ; 1+ node v tl tr 1?+ rot l v tl tr +1 } ; tr 1 se of ń { 1?+ rot r v tl tr 1 ; node v tl tr node v tl tr 1 }}) ; ; 10 Pkging Users don t need to e eposed to the indies on the full tree tpe: here, we pkge it in thee forms. 10.1 Dependent Mp module DependntMp where dt Mp {v} (V : Ke Set v) : Set (k v r) where 12
tree : {h} Bounded.Tree V Bounded. Bounded. h Mp V insertwith : {v} {V : Ke Set v} (k : Ke) V k (V k V k V k) Mp V Mp V insertwith k v f (tree tr) = tree (proj 2 (Bounded.insert k v f tr (lift tt, lift tt))) insert : {v} {V : Ke Set v} (k : Ke) V k Mp V Mp V insert k v = insertwith k v onst lookup : (k : Ke) {v} {V : Ke Set v} Mp V Me (V k) lookup k (tree tr) = Bounded.lookup k tr delete : (k : Ke) {v} {V : Ke Set v} Mp V Mp V delete k (tree tr) with Bounded.delete k tr... tr Bounded. 0 = tree tr... tr Bounded. 1 = tree tr lter : (k : Ke) {v} {V : Ke Set v} (Me (V k) Me (V k)) Mp V Mp V lter k f (tree tr) with Bounded.lter k f tr (lift tt, lift tt)... Bounded.1+ tr = tree tr... Bounded. tr = tree tr... Bounded. tr 1 = tree tr 10.2 Non-Dependent (Simple) Mp module Mp where dt Mp {v} (V : Set v) : Set (k v r) where 13
tree : {h} Bounded.Tree (onst V) Bounded. Bounded. h Mp V insertwith : {v} {V : Set v} (k : Ke) V (V V V) Mp V Mp V insertwith k v f (tree tr) = tree (proj 2 (Bounded.insert k v f tr (lift tt, lift tt))) empt : {v} {V : Set v} Mp V empt = tree (Bounded.lef (lift tt)) insert : {v} {V : Set v} (k : Ke) V Mp V Mp V insert k v = insertwith k v onst lookup : (k : Ke) {v} {V : Set v} Mp V Me V lookup k (tree tr) = Bounded.lookup k tr delete : (k : Ke) {v} {V : Set v} Mp V Mp V delete k (tree tr) with Bounded.delete k tr... tr Bounded. 0 = tree tr... tr Bounded. 1 = tree tr lter : (k : Ke) {v} {V : Set v} (Me V Me V) Mp V Mp V lter k f (tree tr) with Bounded.lter k f tr (lift tt, lift tt)... Bounded.1+ tr = tree tr... Bounded. tr = tree tr... Bounded. tr 1 = tree tr 10.3 Set Note tht we n t ll the tpe itself Set, s tht s reserved word in Agd. module Sets where dt Set : Set (k r) where tree : {h} Bounded.Tree (onst ) Bounded. Bounded. h Set insert : Ke Set Set insert k (tree tr) = 14
tree (proj 2 (Bounded.insert k tt onst tr (lift tt, lift tt))) memer : Ke Set Bool memer k (tree tr) = is-just (Bounded.lookup k tr) delete : (k : Ke) Set Set delete k (tree tr) with Bounded.delete k tr... tr Bounded. 0 = tree tr... tr Bounded. 1 = tree tr Referenes [1] N. A. Dnielsson, The Agd stndrd lirr. [Online]. Aville: https://gd.githu.io/gd-stdli/readme.html [2] C. T. MBride, How to Keep Your Neighours in Order, in Proeedings of the 19th ACM SIG- PLAN Interntionl Conferene on Funtionl Progrmming, ser. ICFP 14. ACM, pp. 297 309. [Online]. Aville: https://personl.is.strth..uk/onor.mride/pu/pivotl.pdf 15