| prelude | |
| import init.core init.system.io init.data.ordering | |
| universe u v w | |
| inductive Rbcolor | |
| | red | black | |
| inductive Rbnode (α : Type u) (β : α → Type v) | |
| | leaf {} : Rbnode | |
| | Node (c : Rbcolor) (lchild : Rbnode) (key : α) (val : β key) (rchild : Rbnode) : Rbnode | |
| instance Rbcolor.DecidableEq : DecidableEq Rbcolor := | |
| {decEq := fun a b => Rbcolor.casesOn a | |
| (Rbcolor.casesOn b (isTrue rfl) (isFalse (fun h => Rbcolor.noConfusion h))) | |
| (Rbcolor.casesOn b (isFalse (fun h => Rbcolor.noConfusion h)) (isTrue rfl))} | |
| namespace Rbnode | |
| variable {α : Type u} {β : α → Type v} {σ : Type w} | |
| open Rbcolor | |
| def depth (f : Nat → Nat → Nat) : Rbnode α β → Nat | |
| | leaf => 0 | |
| | Node _ l _ _ r => (f (depth l) (depth r)) + 1 | |
| protected def min : Rbnode α β → Option (Sigma (fun k => β k)) | |
| | leaf => none | |
| | Node _ leaf k v _ => some ⟨k, v⟩ | |
| | Node _ l k v _ => min l | |
| protected def max : Rbnode α β → Option (Sigma (fun k => β k)) | |
| | leaf => none | |
| | Node _ _ k v leaf => some ⟨k, v⟩ | |
| | Node _ _ k v r => max r | |
| @[specialize] def fold (f : ∀ (k : α), β k → σ → σ) : Rbnode α β → σ → σ | |
| | leaf, b => b | |
| | Node _ l k v r, b => fold r (f k v (fold l b)) | |
| @[specialize] def revFold (f : ∀ (k : α), β k → σ → σ) : Rbnode α β → σ → σ | |
| | leaf, b => b | |
| | Node _ l k v r, b => revFold l (f k v (revFold r b)) | |
| @[specialize] def all (p : ∀ (k : α), β k → Bool) : Rbnode α β → Bool | |
| | leaf => true | |
| | Node _ l k v r => p k v && all l && all r | |
| @[specialize] def any (p : ∀ (k : α), β k → Bool) : Rbnode α β → Bool | |
| | leaf => false | |
| | Node _ l k v r => p k v || any l || any r | |
| def isRed : Rbnode α β → Bool | |
| | Node red _ _ _ _ => true | |
| | _ => false | |
| def rotateLeft : ∀ (n : Rbnode α β), n ≠ leaf → Rbnode α β | |
| | n@(Node hc hl hk hv (Node red xl xk xv xr)), _ => | |
| if !isRed hl | |
| then (Node hc (Node red hl hk hv xl) xk xv xr) | |
| else n | |
| | leaf, h => absurd rfl h | |
| | e, _ => e | |
| theorem ifNodeNodeNeLeaf {c : Prop} [Decidable c] {l1 l2 : Rbnode α β} {c1 k1 v1 r1 c2 k2 v2 r2} : (if c then Node c1 l1 k1 v1 r1 else Node c2 l2 k2 v2 r2) ≠ leaf := | |
| fun h => if hc : c | |
| then have h1 : (if c then Node c1 l1 k1 v1 r1 else Node c2 l2 k2 v2 r2) = Node c1 l1 k1 v1 r1 from ifPos hc; | |
| Rbnode.noConfusion (Eq.trans h1.symm h) | |
| else have h1 : (if c then Node c1 l1 k1 v1 r1 else Node c2 l2 k2 v2 r2) = Node c2 l2 k2 v2 r2 from ifNeg hc; | |
| Rbnode.noConfusion (Eq.trans h1.symm h) | |
| theorem rotateLeftNeLeaf : ∀ (n : Rbnode α β) (h : n ≠ leaf), rotateLeft n h ≠ leaf | |
| | Node _ hl _ _ (Node red _ _ _ _), _, h => ifNodeNodeNeLeaf h | |
| | leaf, h, _ => absurd rfl h | |
| | Node _ _ _ _ (Node black _ _ _ _), _, h => Rbnode.noConfusion h | |
| def rotateRight : ∀ (n : Rbnode α β), n ≠ leaf → Rbnode α β | |
| | n@(Node hc (Node red xl xk xv xr) hk hv hr), _ => | |
| if isRed xl | |
| then (Node hc xl xk xv (Node red xr hk hv hr)) | |
| else n | |
| | leaf, h => absurd rfl h | |
| | e, _ => e | |
| theorem rotateRightNeLeaf : ∀ (n : Rbnode α β) (h : n ≠ leaf), rotateRight n h ≠ leaf | |
| | Node _ (Node red _ _ _ _) _ _ _, _, h => ifNodeNodeNeLeaf h | |
| | leaf, h, _ => absurd rfl h | |
| | Node _ (Node black _ _ _ _) _ _ _, _, h => Rbnode.noConfusion h | |
| def flip : Rbcolor → Rbcolor | |
| | red => black | |
| | black => red | |
| def flipColor : Rbnode α β → Rbnode α β | |
| | Node c l k v r => Node (flip c) l k v r | |
| | leaf => leaf | |
| def flipColors : ∀ (n : Rbnode α β), n ≠ leaf → Rbnode α β | |
| | n@(Node c l k v r), _ => | |
| if isRed l ∧ isRed r | |
| then Node (flip c) (flipColor l) k v (flipColor r) | |
| else n | |
| | leaf, h => absurd rfl h | |
| def fixup (n : Rbnode α β) (h : n ≠ leaf) : Rbnode α β := | |
| let n₁ := rotateLeft n h; | |
| let h₁ := (rotateLeftNeLeaf n h); | |
| let n₂ := rotateRight n₁ h₁; | |
| let h₂ := (rotateRightNeLeaf n₁ h₁); | |
| flipColors n₂ h₂ | |
| def setBlack : Rbnode α β → Rbnode α β | |
| | Node red l k v r => Node black l k v r | |
| | n => n | |
| section insert | |
| variable (lt : α → α → Prop) [DecidableRel lt] | |
| def ins (x : α) (vx : β x) : Rbnode α β → Rbnode α β | |
| | leaf => Node red leaf x vx leaf | |
| | Node c l k v r => | |
| if lt x k then fixup (Node c (ins l) k v r) (fun h => Rbnode.noConfusion h) | |
| else if lt k x then fixup (Node c l k v (ins r)) (fun h => Rbnode.noConfusion h) | |
| else Node c l x vx r | |
| def insert (t : Rbnode α β) (k : α) (v : β k) : Rbnode α β := | |
| setBlack (ins lt k v t) | |
| end insert | |
| section membership | |
| variable (lt : α → α → Prop) | |
| variable [DecidableRel lt] | |
| def findCore : Rbnode α β → ∀ (k : α), Option (Sigma (fun k => β k)) | |
| | leaf, x => none | |
| | Node _ a ky vy b, x => | |
| (match cmpUsing lt x ky with | |
| | Ordering.lt => findCore a x | |
| | Ordering.Eq => some ⟨ky, vy⟩ | |
| | Ordering.gt => findCore b x) | |
| def find {β : Type v} : Rbnode α (fun _ => β) → α → Option β | |
| | leaf, x => none | |
| | Node _ a ky vy b, x => | |
| (match cmpUsing lt x ky with | |
| | Ordering.lt => find a x | |
| | Ordering.Eq => some vy | |
| | Ordering.gt => find b x) | |
| def lowerBound : Rbnode α β → α → Option (Sigma β) → Option (Sigma β) | |
| | leaf, x, lb => lb | |
| | Node _ a ky vy b, x, lb => | |
| (match cmpUsing lt x ky with | |
| | Ordering.lt => lowerBound a x lb | |
| | Ordering.Eq => some ⟨ky, vy⟩ | |
| | Ordering.gt => lowerBound b x (some ⟨ky, vy⟩)) | |
| end membership | |
| inductive WellFormed (lt : α → α → Prop) : Rbnode α β → Prop | |
| | leafWff : WellFormed leaf | |
| | insertWff {n n' : Rbnode α β} {k : α} {v : β k} [DecidableRel lt] : WellFormed n → n' = insert lt n k v → WellFormed n' | |
| end Rbnode | |
| open Rbnode | |
| /- TODO(Leo): define dRbmap -/ | |
| def Rbmap (α : Type u) (β : Type v) (lt : α → α → Prop) : Type (max u v) := | |
| {t : Rbnode α (fun _ => β) // t.WellFormed lt } | |
| @[inline] def mkRbmap (α : Type u) (β : Type v) (lt : α → α → Prop) : Rbmap α β lt := | |
| ⟨leaf, WellFormed.leafWff lt⟩ | |
| namespace Rbmap | |
| variable {α : Type u} {β : Type v} {σ : Type w} {lt : α → α → Prop} | |
| def depth (f : Nat → Nat → Nat) (t : Rbmap α β lt) : Nat := | |
| t.val.depth f | |
| @[inline] def fold (f : α → β → σ → σ) : Rbmap α β lt → σ → σ | |
| | ⟨t, _⟩, b => t.fold f b | |
| @[inline] def revFold (f : α → β → σ → σ) : Rbmap α β lt → σ → σ | |
| | ⟨t, _⟩, b => t.revFold f b | |
| @[inline] def empty : Rbmap α β lt → Bool | |
| | ⟨leaf, _⟩ => true | |
| | _ => false | |
| @[specialize] def toList : Rbmap α β lt → List (α × β) | |
| | ⟨t, _⟩ => t.revFold (fun k v ps => (k, v)::ps) [] | |
| @[inline] protected def min : Rbmap α β lt → Option (α × β) | |
| | ⟨t, _⟩ => | |
| match t.min with | |
| | some ⟨k, v⟩ => some (k, v) | |
| | none => none | |
| @[inline] protected def max : Rbmap α β lt → Option (α × β) | |
| | ⟨t, _⟩ => | |
| match t.max with | |
| | some ⟨k, v⟩ => some (k, v) | |
| | none => none | |
| instance [Repr α] [Repr β] : Repr (Rbmap α β lt) := | |
| ⟨fun t => "rbmapOf " ++ repr t.toList⟩ | |
| variable [DecidableRel lt] | |
| def insert : Rbmap α β lt → α → β → Rbmap α β lt | |
| | ⟨t, w⟩, k, v => ⟨t.insert lt k v, WellFormed.insertWff w rfl⟩ | |
| @[specialize] def ofList : List (α × β) → Rbmap α β lt | |
| | [] => mkRbmap _ _ _ | |
| | ⟨k,v⟩::xs => (ofList xs).insert k v | |
| def findCore : Rbmap α β lt → α → Option (Sigma (fun (k : α) => β)) | |
| | ⟨t, _⟩, x => t.findCore lt x | |
| def find : Rbmap α β lt → α → Option β | |
| | ⟨t, _⟩, x => t.find lt x | |
| /-- (lowerBound k) retrieves the kv pair of the largest key smaller than or equal to `k`, | |
| if it exists. -/ | |
| def lowerBound : Rbmap α β lt → α → Option (Sigma (fun (k : α) => β)) | |
| | ⟨t, _⟩, x => t.lowerBound lt x none | |
| @[inline] def contains (t : Rbmap α β lt) (a : α) : Bool := | |
| (t.find a).isSome | |
| def fromList (l : List (α × β)) (lt : α → α → Prop) [DecidableRel lt] : Rbmap α β lt := | |
| l.foldl (fun r p => r.insert p.1 p.2) (mkRbmap α β lt) | |
| @[inline] def all : Rbmap α β lt → (α → β → Bool) → Bool | |
| | ⟨t, _⟩, p => t.all p | |
| @[inline] def any : Rbmap α β lt → (α → β → Bool) → Bool | |
| | ⟨t, _⟩, p => t.any p | |
| end Rbmap | |
| def rbmapOf {α : Type u} {β : Type v} (l : List (α × β)) (lt : α → α → Prop) [DecidableRel lt] : Rbmap α β lt := | |
| Rbmap.fromList l lt | |
| /- Test -/ | |
| @[reducible] def map : Type := Rbmap Nat Bool Less.Less | |
| def mkMapAux : Nat → map → map | |
| | 0, m => m | |
| | n+1, m => mkMapAux n (m.insert n (n % 10 = 0)) | |
| def mkMap (n : Nat) := | |
| mkMapAux n (mkRbmap Nat Bool Less.Less) | |
| def main (xs : List String) : IO UInt32 := | |
| let m := mkMap xs.head.toNat; | |
| let v := Rbmap.fold (fun (k : Nat) (v : Bool) (r : Nat) => if v then r + 1 else r) m 0; | |
| IO.println (toString v) *> | |
| pure 0 |