get delete, leftMost, rightMost, pop working for SortedMap
required fixing an issue in case building.
This commit is contained in:
@@ -2,6 +2,10 @@ module SortedMap
|
||||
|
||||
import Prelude
|
||||
|
||||
-- TODO We'll want to replace Ord/Eq with (a → Ordering) (and rewrite most of our aoc solutions...)
|
||||
-- data Ordering : U where
|
||||
-- LT EQ GT : Ordering
|
||||
|
||||
data T23 : Nat -> U -> U -> U where
|
||||
Leaf : ∀ k v. k -> v -> T23 Z k v
|
||||
Node2 : ∀ h k v. T23 h k v -> k -> T23 h k v -> T23 (S h) k v
|
||||
@@ -43,9 +47,127 @@ insertT23 key value (Node3 t1 k1 t2 k2 t3) =
|
||||
Left t3' => Left (Node3 t1 k1 t2 k2 t3')
|
||||
Right (a,b,c) => Right (Node2 t1 k1 t2, k2, Node2 a b c)
|
||||
|
||||
-- This is cribbed from Idris. Deleting nodes takes a bit of code.
|
||||
Hole : Nat → U → U → U
|
||||
Hole Z k v = Unit
|
||||
Hole (S n) k v = T23 n k v
|
||||
|
||||
Node4 : ∀ k v h. T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → T23 (S (S h)) k v
|
||||
Node4 t1 k1 t2 k2 t3 k3 t4 = Node2 (Node2 t1 k1 t2) k2 (Node2 t3 k3 t4)
|
||||
|
||||
Node5 : ∀ k v h. T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → T23 (S (S h)) k v
|
||||
Node5 a b c d e f g h i = Node2 (Node2 a b c) d (Node3 e f g h i)
|
||||
|
||||
Node6 : ∀ k v h. T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → T23 (S (S h)) k v
|
||||
Node6 a b c d e f g h i j k = Node2 (Node3 a b c d e) f (Node3 g h i j k)
|
||||
|
||||
Node7 : ∀ k v h. T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → k → T23 h k v → T23 (S (S h)) k v
|
||||
Node7 a b c d e f g h i j k l m = Node3 (Node3 a b c d e) f (Node2 g h i) j (Node2 k l m)
|
||||
|
||||
merge1 : ∀ k v h. T23 h k v → k → T23 (S h) k v → k → T23 (S h) k v → T23 (S (S h)) k v
|
||||
merge1 a b (Node2 c d e) f (Node2 g h i) = Node5 a b c d e f g h i
|
||||
merge1 a b (Node2 c d e) f (Node3 g h i j k) = Node6 a b c d e f g h i j k
|
||||
merge1 a b (Node3 c d e f g) h (Node2 i j k) = Node6 a b c d e f g h i j k
|
||||
merge1 a b (Node3 c d e f g) h (Node3 i j k l m) = Node7 a b c d e f g h i j k l m
|
||||
|
||||
merge2 : ∀ k v h. T23 (S h) k v → k → T23 h k v → k → T23 (S h) k v → T23 (S (S h)) k v
|
||||
merge2 (Node2 a b c) d e f (Node2 g h i) = Node5 a b c d e f g h i
|
||||
merge2 (Node2 a b c) d e f (Node3 g h i j k) = Node6 a b c d e f g h i j k
|
||||
merge2 (Node3 a b c d e) f g h (Node2 i j k) = Node6 a b c d e f g h i j k
|
||||
merge2 (Node3 a b c d e) f g h (Node3 i j k l m) = Node7 a b c d e f g h i j k l m
|
||||
|
||||
merge3 : ∀ k v h. T23 (S h) k v → k → T23 (S h) k v → k → T23 h k v → T23 (S (S h)) k v
|
||||
merge3 (Node2 a b c) d (Node2 e f g) h i = Node5 a b c d e f g h i
|
||||
merge3 (Node2 a b c) d (Node3 e f g h i) j k = Node6 a b c d e f g h i j k
|
||||
merge3 (Node3 a b c d e) f (Node2 g h i) j k = Node6 a b c d e f g h i j k
|
||||
merge3 (Node3 a b c d e) f (Node3 g h i j k) l m = Node7 a b c d e f g h i j k l m
|
||||
|
||||
-- height is erased in the data everywhere but the top, but needed for case
|
||||
-- I wonder if we could use a 1 + 1 + 1 type instead of Either Tree Hole and condense this
|
||||
deleteT23 : ∀ k v. {{Ord k}} {{Eq k}} → (h : Nat) -> k -> T23 h k v -> Either (T23 h k v) (Hole h k v)
|
||||
deleteT23 Z key (Leaf k v) = if k == key then Right MkUnit else Left (Leaf k v)
|
||||
deleteT23 (S Z) key (Node2 t1 k1 t2) =
|
||||
if key <= k1
|
||||
then case deleteT23 Z key t1 of
|
||||
Left t1 => Left (Node2 t1 k1 t2)
|
||||
Right _ => Right t2
|
||||
else case deleteT23 Z key t2 of
|
||||
Left t2 => Left (Node2 t1 k1 t2)
|
||||
Right MkUnit => Right t1
|
||||
deleteT23 (S Z) key (Node3 t1 k1 t2 k2 t3) =
|
||||
if key <= k1
|
||||
then case deleteT23 _ key t1 of
|
||||
Left t1 => Left (Node3 t1 k1 t2 k2 t3)
|
||||
Right MkUnit => Left (Node2 t2 k2 t3)
|
||||
else if key <= k2 then case deleteT23 _ key t2 of
|
||||
Left t2 => Left (Node3 t1 k1 t2 k2 t3)
|
||||
Right _ => Left (Node2 t1 k1 t3)
|
||||
else case deleteT23 _ key t3 of
|
||||
Left t3 => Left (Node3 t1 k1 t2 k2 t3)
|
||||
Right _ => Left (Node2 t1 k1 t2)
|
||||
deleteT23 (S (S h)) key (Node2 t1 k1 t2) =
|
||||
if key <= k1
|
||||
then case deleteT23 (S h) key t1 of
|
||||
Left t1 => Left (Node2 t1 k1 t2)
|
||||
Right t1 => case t2 of
|
||||
Node2 t2' k2' t3' => Right (Node3 t1 k1 t2' k2' t3')
|
||||
Node3 t2 k2 t3 k3 t4 => Left $ Node4 t1 k1 t2 k2 t3 k3 t4
|
||||
else case deleteT23 _ key t2 of
|
||||
Left t2 => Left (Node2 t1 k1 t2)
|
||||
Right t2 => case t1 of
|
||||
Node2 a b c => Right (Node3 a b c k1 t2)
|
||||
Node3 a b c d e => Left (Node4 a b c d e k1 t2)
|
||||
deleteT23 (S (S h)) key (Node3 t1 k1 t2 k2 t3) =
|
||||
if key <= k1
|
||||
then case deleteT23 _ key t1 of
|
||||
Left t1 => Left (Node3 t1 k1 t2 k2 t3)
|
||||
Right t1 => Left (merge1 t1 k1 t2 k2 t3)
|
||||
else if key <= k2 then case deleteT23 _ key t2 of
|
||||
Left t2 => Left (Node3 t1 k1 t2 k2 t3)
|
||||
Right t2 => Left (merge2 t1 k1 t2 k2 t3)
|
||||
else case deleteT23 _ key t3 of
|
||||
Left t3 => Left (Node3 t1 k1 t2 k2 t3)
|
||||
Right t3 => Left (merge3 t1 k1 t2 k2 t3)
|
||||
|
||||
treeLeft : ∀ h k v. T23 h k v → (k × v)
|
||||
treeLeft (Leaf k v) = (k, v)
|
||||
treeLeft (Node2 t1 _ _) = treeLeft t1
|
||||
treeLeft (Node3 t1 _ _ _ _) = treeLeft t1
|
||||
|
||||
treeRight : ∀ h k v. T23 h k v → (k × v)
|
||||
treeRight (Leaf k v) = (k, v)
|
||||
treeRight (Node2 _ _ t2) = treeRight t2
|
||||
treeRight (Node3 _ _ _ _ t3) = treeRight t3
|
||||
|
||||
|
||||
data SortedMap : U -> U -> U where
|
||||
EmptyMap : ∀ k v. SortedMap k v
|
||||
MapOf : ∀ k v h. T23 h k v -> SortedMap k v
|
||||
-- not erased so we know what happens in delete
|
||||
MapOf : ∀ k v. {h : Nat} → T23 h k v -> SortedMap k v
|
||||
|
||||
deleteMap : ∀ k v. {{Ord k}} {{Eq k}} → k → SortedMap k v → SortedMap k v
|
||||
deleteMap key EmptyMap = EmptyMap
|
||||
-- REVIEW if I split h separately in a nested case, it doesn't sort out Hole
|
||||
deleteMap key (MapOf {k} {v} {Z} tree) = case deleteT23 Z key tree of
|
||||
Left t => MapOf t
|
||||
Right t => EmptyMap
|
||||
deleteMap key (MapOf {k} {v} {S n} tree) = case deleteT23 (S n) key tree of
|
||||
Left t => MapOf t
|
||||
Right t => MapOf t
|
||||
|
||||
leftMost : ∀ k v. SortedMap k v → Maybe (k × v)
|
||||
leftMost EmptyMap = Nothing
|
||||
leftMost (MapOf m) = Just (treeLeft m)
|
||||
|
||||
rightMost : ∀ k v. SortedMap k v → Maybe (k × v)
|
||||
rightMost EmptyMap = Nothing
|
||||
rightMost (MapOf m) = Just (treeRight m)
|
||||
|
||||
-- TODO issue with metas and case if written as `do` block
|
||||
pop : ∀ k v. {{Eq k}} {{Ord k}} → SortedMap k v → Maybe ((k × v) × SortedMap k v)
|
||||
pop m = case leftMost m of
|
||||
Just (k,v) => Just ((k,v), deleteMap k m)
|
||||
Nothing => Nothing
|
||||
|
||||
lookupMap : ∀ k v. {{Ord k}} {{Eq k}} -> k -> SortedMap k v -> Maybe (k × v)
|
||||
lookupMap k EmptyMap = Nothing
|
||||
|
||||
Reference in New Issue
Block a user