forked from leanprover/lean4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDRBMap.lean
151 lines (111 loc) · 5.65 KB
/
DRBMap.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/-
Copyright (c) 2022 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura, Mac Malone
-/
import Lean.Data.RBMap
import Lake.Util.Compare
namespace Lake
open Lean RBNode
/-!
This module includes a dependently typed adaption of the `Lean.RBMap`
defined in `Lean.Data.RBMap` module of the Lean core. Most of the code is
copied directly from there with only minor edits.
-/
instance inhabitedOfEmptyCollection [EmptyCollection α] : Inhabited α where
default := {}
@[specialize] def RBNode.dFind {α : Type u} {β : α → Type v}
(cmp : α → α → Ordering) [h : EqOfCmpWrt α β cmp] : RBNode α β → (k : α) → Option (β k)
| leaf, _ => none
| node _ a ky vy b, x =>
match ho:cmp x ky with
| Ordering.lt => dFind cmp a x
| Ordering.gt => dFind cmp b x
| Ordering.eq => some <| cast (by rw [eq_of_cmp_wrt (f := β) ho]) vy
/-- A Dependently typed `RBMap`. -/
def DRBMap (α : Type u) (β : α → Type v) (cmp : α → α → Ordering) : Type (max u v) :=
{t : RBNode α β // t.WellFormed cmp }
instance : Coe (DRBMap α (fun _ => β) cmp) (RBMap α β cmp) := ⟨id⟩
@[inline] def mkDRBMap (α : Type u) (β : α → Type v) (cmp : α → α → Ordering) : DRBMap α β cmp :=
⟨leaf, WellFormed.leafWff⟩
@[inline] def DRBMap.empty {α : Type u} {β : α → Type v} {cmp : α → α → Ordering} : DRBMap α β cmp :=
mkDRBMap ..
instance (α : Type u) (β : α → Type v) (cmp : α → α → Ordering) : EmptyCollection (DRBMap α β cmp) :=
⟨DRBMap.empty⟩
namespace DRBMap
variable {α : Type u} {β : α → Type v} {σ : Type w} {cmp : α → α → Ordering}
def depth (f : Nat → Nat → Nat) (t : DRBMap α β cmp) : Nat :=
t.val.depth f
@[inline] def fold (f : σ → (k : α) → β k → σ) : (init : σ) → DRBMap α β cmp → σ
| b, ⟨t, _⟩ => t.fold f b
@[inline] def revFold (f : σ → (k : α) → β k → σ) : (init : σ) → DRBMap α β cmp → σ
| b, ⟨t, _⟩ => t.revFold f b
@[inline] def foldM [Monad m] (f : σ → (k : α) → β k → m σ) : (init : σ) → DRBMap α β cmp → m σ
| b, ⟨t, _⟩ => t.foldM f b
@[inline] def forM [Monad m] (f : (k : α) → β k → m PUnit) (t : DRBMap α β cmp) : m PUnit :=
t.foldM (fun _ k v => f k v) ⟨⟩
@[inline] protected def forIn [Monad m] (t : DRBMap α β cmp) (init : σ) (f : ((k : α) × β k) → σ → m (ForInStep σ)) : m σ :=
t.val.forIn init (fun a b acc => f ⟨a, b⟩ acc)
instance : ForIn m (DRBMap α β cmp) ((k : α) × β k) where
forIn := DRBMap.forIn
@[inline] def isEmpty : DRBMap α β cmp → Bool
| ⟨leaf, _⟩ => true
| _ => false
@[specialize] def toList : DRBMap α β cmp → List ((k : α) × β k)
| ⟨t, _⟩ => t.revFold (fun ps k v => ⟨k, v⟩::ps) []
@[inline] protected def min : DRBMap α β cmp → Option ((k : α) × β k)
| ⟨t, _⟩ =>
match t.min with
| some ⟨k, v⟩ => some ⟨k, v⟩
| none => none
@[inline] protected def max : DRBMap α β cmp → Option ((k : α) × β k)
| ⟨t, _⟩ =>
match t.max with
| some ⟨k, v⟩ => some ⟨k, v⟩
| none => none
instance [Repr ((k : α) × β k)] : Repr (DRBMap α β cmp) where
reprPrec m prec := Repr.addAppParen ("Lake.drbmapOf " ++ repr m.toList) prec
@[inline] def insert : DRBMap α β cmp → (k : α) → β k → DRBMap α β cmp
| ⟨t, w⟩, k, v => ⟨t.insert cmp k v, WellFormed.insertWff w rfl⟩
@[inline] def erase : DRBMap α β cmp → α → DRBMap α β cmp
| ⟨t, w⟩, k => ⟨t.erase cmp k, WellFormed.eraseWff w rfl⟩
@[specialize] def ofList : List ((k : α) × β k) → DRBMap α β cmp
| [] => mkDRBMap ..
| ⟨k,v⟩::xs => (ofList xs).insert k v
@[inline] def findCore? : DRBMap α β cmp → α → Option ((k : α) × β k)
| ⟨t, _⟩, x => t.findCore cmp x
@[inline] def find? [EqOfCmpWrt α β cmp] : DRBMap α β cmp → (k : α) → Option (β k)
| ⟨t, _⟩, x => RBNode.dFind cmp t x
@[inline] def findD [EqOfCmpWrt α β cmp] (t : DRBMap α β cmp) (k : α) (v₀ : β k) : β k :=
(t.find? k).getD v₀
/-- (lowerBound k) retrieves the kv pair of the largest key smaller than or equal to `k`,
if it exists. -/
@[inline] def lowerBound : DRBMap α β cmp → α → Option ((k : α) × β k)
| ⟨t, _⟩, x => t.lowerBound cmp x none
@[inline] def contains [EqOfCmpWrt α β cmp] (t : DRBMap α β cmp) (k : α) : Bool :=
(t.find? k).isSome
@[inline] def fromList (l : List ((k : α) × β k)) (cmp : α → α → Ordering) : DRBMap α β cmp :=
l.foldl (fun r p => r.insert p.1 p.2) (mkDRBMap α β cmp)
@[inline] def all : DRBMap α β cmp → ((k : α) → β k → Bool) → Bool
| ⟨t, _⟩, p => t.all p
@[inline] def any : DRBMap α β cmp → ((k : α) → β k → Bool) → Bool
| ⟨t, _⟩, p => t.any p
def size (m : DRBMap α β cmp) : Nat :=
m.fold (fun sz _ _ => sz+1) 0
def maxDepth (t : DRBMap α β cmp) : Nat :=
t.val.depth Nat.max
@[inline] def min! [Inhabited ((k : α) × β k)] (t : DRBMap α β cmp) : (k : α) × β k :=
match t.min with
| some p => p
| none => panic! "map is empty"
@[inline] def max! [Inhabited ((k : α) × β k)] (t : DRBMap α β cmp) : (k : α) × β k :=
match t.max with
| some p => p
| none => panic! "map is empty"
@[inline] def find! [EqOfCmpWrt α β cmp] (t : DRBMap α β cmp) (k : α) [Inhabited (β k)] : β k :=
match t.find? k with
| some b => b
| none => panic! "key is not in the map"
end DRBMap
def drbmapOf {α : Type u} {β : α → Type v} (l : List ((k : α) × (β k))) (cmp : α → α → Ordering) : DRBMap α β cmp :=
DRBMap.fromList l cmp