module AATree where
open import Relation.Binary
postulate
A : Set
_<_ : A → A → Set
_≈A_ : A → A → Set
trans : {a b c : A} → a < b → b < c → a < c
compare : ∀ x y → Tri (x < y) (x ≈A y) (y < x)
open import Data.Unit
open import Data.Product
import Data.Nat as Nat
open Nat hiding (compare) renaming (_<_ to _<ℕ_; _≤_ to _≤ℕ_)
open import Data.Nat.Properties
open DecTotalOrder Nat.decTotalOrder hiding (_≈_; refl) renaming (trans to transℕ)
open StrictTotalOrder strictTotalOrder hiding (_<_; trans) renaming (compare to compareℕ)
import Relation.Binary.PropositionalEquality as RBP
open RBP hiding (trans)
data Tree : Set where
lf : Tree
nd : A → ℕ → Tree → Tree → Tree
level : Tree → ℕ
level lf = 0
level (nd _ n _ _) = n
skew : Tree → Tree
skew (nd a n (nd la ln ll lr) r) with compareℕ n ln
... | tri≈ _ _ _ = nd la ln ll (nd a n lr r)
... | _ = nd a n (nd la ln ll lr) r
skew t = t
split : Tree → Tree
split (nd a n l (nd ra rn rl rr)) with compareℕ n (level rr)
... | tri≈ _ _ _ = nd ra (rn + 1) (nd a n l rl) rr
... | _ = nd a n l (nd ra rn rl rr)
split t = t
insert : A → Tree → Tree
insert a lf = nd a 1 lf lf
insert a (nd b n l r) with compare a b
... | tri< _ _ _ = split (skew (nd b n (insert a l) r))
... | tri≈ _ _ _ = nd b n l r
... | tri> _ _ _ = split (skew (nd b n l (insert a r)))
_>T_ : A → Tree → Set
_ >T lf = ⊤
a >T (nd b _ l r) = (b < a) × (a >T l) × (a >T r)
_<T_ : A → Tree → Set
_ <T lf = ⊤
a <T (nd b _ l r) = (a < b) × (a <T l) × (a <T r)
Sorted : Tree → Set
Sorted lf = ⊤
Sorted (nd a _ l r) = (a >T l × Sorted l) × (a <T r × Sorted r)
sorted-split : (t : Tree) → Sorted t → Sorted (split t)
sorted-split lf _ = tt
sorted-split (nd a n l lf) p = p
sorted-split (nd a n lf (nd ra rn rl rr))
(p , ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
with compareℕ n (level rr)
... | tri≈ _ _ _ = ((a<ra , tt , ra>Trl) , (tt , tt) , a<Trl , srl) , ra<Trr , srr
... | tri< _ _ _ = (p , ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
... | tri> _ _ _ = (p , ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
sorted-split (nd a n (nd la ln ll lr) (nd ra rn rl rr))
( ((la<a , a>Tll , a>Tlr) , (la>Tll , sll) , (la<Tlr , slr))
, ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
with compareℕ n (level rr)
... | tri≈ _ _ _ = ((a<ra , (trans la<a a<ra , lem ll a<ra a>Tll , lem lr a<ra a>Tlr) , ra>Trl)
, ((la<a , a>Tll , a>Tlr) , (la>Tll , sll) , la<Tlr , slr) ,
a<Trl , srl) , ra<Trr , srr
where
lem : {a b : A}(t : Tree) → b < a → b >T t → a >T t
lem lf _ _ = tt
lem (nd x n l r) b<a (x<b , b>Tl , b>Tr) = trans x<b b<a , lem l b<a b>Tl , lem r b<a b>Tr
... | tri< _ _ _ = ( ((la<a , a>Tll , a>Tlr) , (la>Tll , sll) , (la<Tlr , slr))
, ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
... | tri> _ _ _ = ( ((la<a , a>Tll , a>Tlr) , (la>Tll , sll) , (la<Tlr , slr))
, ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
sorted-skew : (t : Tree) → Sorted t → Sorted (skew t)
sorted-skew lf _ = tt
sorted-skew (nd _ _ lf _) p = p
sorted-skew (nd a n (nd la ln ll lr) lf)
(((la<a , a>Tll , a>Tlr) , (la<Trl , sll) , (la<Tlr , slr)) , _) with compareℕ n ln
... | tri≈ _ _ _ = (la<Trl , sll) , (la<a , la<Tlr , tt) , (a>Tlr , slr) , tt , tt
... | tri< _ _ _ = (((la<a , a>Tll , a>Tlr) , (la<Trl , sll) , (la<Tlr , slr)) , (tt , tt))
... | tri> _ _ _ = (((la<a , a>Tll , a>Tlr) , (la<Trl , sll) , (la<Tlr , slr)) , (tt , tt))
sorted-skew (nd a n (nd la ln ll lr) (nd ra rn rl rr))
( ((la<a , a>Tll , a>Tlr) , (la>Tll , sll) , (la<Tlr , slr))
, ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
with compareℕ n ln
... | tri≈ _ _ _ = (la>Tll , sll)
, ((la<a , la<Tlr , trans la<a a<ra , lem rl la<a a<Trl , lem rr la<a a<Trr)
, (a>Tlr , slr) , (a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , ra<Trr , srr)
where
lem : {a b : A}(t : Tree) → a < b → b <T t → a <T t
lem lf _ _ = tt
lem (nd x n l r) a<b (b<x , b<Tl , b<Tr) = trans a<b b<x , lem l a<b b<Tl , lem r a<b b<Tr
... | tri< _ _ _ = ( ((la<a , a>Tll , a>Tlr) , (la>Tll , sll) , (la<Tlr , slr))
, ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
... | tri> _ _ _ = ( ((la<a , a>Tll , a>Tlr) , (la>Tll , sll) , (la<Tlr , slr))
, ((a<ra , a<Trl , a<Trr) , (ra>Trl , srl) , (ra<Trr , srr)))
sorted-split-skew : (t : Tree) → Sorted t → Sorted (split (skew t))
sorted-split-skew t p = sorted-split (skew t) (sorted-skew t p)
g-split : (b : A)(t : Tree) → b >T t → b >T split t
g-split _ lf _ = tt
g-split _ (nd _ _ _ lf) p = p
g-split b (nd c n l (nd ra rn rl rr)) (c<b , pl , (ra<b , b>Trl , b>Trr))
with compareℕ n (level rr)
... | tri≈ _ _ _ = ra<b , (c<b , pl , b>Trl) , b>Trr
... | tri< _ _ _ = c<b , pl , ra<b , b>Trl , b>Trr
... | tri> _ _ _ = c<b , pl , ra<b , b>Trl , b>Trr
l-split : (b : A)(t : Tree) → b <T t → b <T split t
l-split _ lf _ = tt
l-split _ (nd _ _ _ lf) p = p
l-split b (nd c n l (nd ra rn rl rr)) (c<b , pl , (ra<b , b>Trl , b>Trr))
with compareℕ n (level rr)
... | tri≈ _ _ _ = ra<b , (c<b , pl , b>Trl) , b>Trr
... | tri< _ _ _ = c<b , pl , ra<b , b>Trl , b>Trr
... | tri> _ _ _ = c<b , pl , ra<b , b>Trl , b>Trr
g-skew : (b : A)(t : Tree) → b >T t → b >T skew t
g-skew _ lf _ = tt
g-skew _ (nd _ _ lf r) p = p
g-skew b (nd a n (nd la ln ll lr) r) (a<b , (la<b , b>Tll , b>Tlr) , pr) with compareℕ n ln
... | tri≈ _ _ _ = la<b , b>Tll , a<b , b>Tlr , pr
... | tri< _ _ _ = (a<b , (la<b , b>Tll , b>Tlr) , pr)
... | tri> _ _ _ = (a<b , (la<b , b>Tll , b>Tlr) , pr)
l-skew : (b : A)(t : Tree) → b <T t → b <T skew t
l-skew _ lf _ = tt
l-skew _ (nd _ _ lf r) p = p
l-skew b (nd a n (nd la ln ll lr) r) (a<b , (la<b , b>Tll , b>Tlr) , pr) with compareℕ n ln
... | tri≈ _ _ _ = la<b , b>Tll , a<b , b>Tlr , pr
... | tri< _ _ _ = (a<b , (la<b , b>Tll , b>Tlr) , pr)
... | tri> _ _ _ = (a<b , (la<b , b>Tll , b>Tlr) , pr)
g-split-skew : (b : A)(t : Tree) → b >T t → b >T split (skew t)
g-split-skew b t p = g-split b (skew t) (g-skew b t p)
l-split-skew : (b : A)(t : Tree) → b <T t → b <T split (skew t)
l-split-skew b t p = l-split b (skew t) (l-skew b t p)
lemmaˡ : (a b : A) → (t : Tree) → a < b → b >T t → b >T (insert a t)
lemmaˡ _ _ lf a<b _ = (a<b , tt , tt)
lemmaˡ a b (nd c n l r) a<b (c<b , b>Tl , b>Tr) with compare a c
... | tri< a<c _ _ = g-split-skew b (nd c n (insert a l) r) (c<b , lemmaˡ a b l a<b b>Tl , b>Tr)
... | tri≈ _ _ _ = c<b , b>Tl , b>Tr
... | tri> _ _ c<a = g-split-skew b (nd c n l (insert a r)) (c<b , b>Tl , lemmaˡ a b r a<b b>Tr)
lemmaʳ : (a b : A) → (t : Tree) → b < a → b <T t → b <T (insert a t)
lemmaʳ _ _ lf a<b _ = (a<b , tt , tt)
lemmaʳ a b (nd c n l r) a<b (c<b , b>Tl , b>Tr) with compare a c
... | tri< a<c _ _ = l-split-skew b (nd c n (insert a l) r) (c<b , lemmaʳ a b l a<b b>Tl , b>Tr)
... | tri≈ _ _ _ = c<b , b>Tl , b>Tr
... | tri> _ _ c<a = l-split-skew b (nd c n l (insert a r)) (c<b , b>Tl , lemmaʳ a b r a<b b>Tr)
sorted : (a : A)(t : Tree) → Sorted t → Sorted (insert a t)
sorted _ lf _ = (tt , tt) , (tt , tt)
sorted a (nd b n l r) ((b>Tl , sl) , (b<Tr , sr)) with compare a b
... | tri< a<b _ _ = sorted-split-skew (nd b n (insert a l) r)
((lemmaˡ a b l a<b b>Tl , sorted a l sl) , b<Tr , sr)
... | tri≈ _ _ _ = ((b>Tl , sl) , (b<Tr , sr))
... | tri> _ _ b<a = sorted-split-skew (nd b n l (insert a r))
((b>Tl , sl) , lemmaʳ a b r b<a b<Tr , sorted a r sr)