@@ -56,15 +56,47 @@ be used in nested inductive types. For these use cases, `Std.DHashMap.Raw` and
5656`Std.DHashMap.Raw.WF` unbundle the invariant from the hash map. When in doubt, prefer
5757`DHashMap` over `DHashMap.Raw`.
5858-/
59- def ExtDHashMap (α : Type u) (β : α → Type v) [BEq α] [Hashable α] :=
60- Quotient (DHashMap.isSetoid α β)
59+ structure ExtDHashMap (α : Type u) (β : α → Type v) [BEq α] [Hashable α] where
60+ /-- Internal implementation detail of the hash map. -/
61+ mk' ::
62+ /-- Internal implementation detail of the hash map. -/
63+ inner : Quotient (DHashMap.isSetoid α β)
6164
6265namespace ExtDHashMap
6366
67+ /-- Internal implementation detail of the hash map. -/
68+ abbrev mk (m : DHashMap α β) : ExtDHashMap α β :=
69+ mk' (.mk _ m)
70+
71+ /-- Internal implementation detail of the hash map. -/
72+ abbrev lift {γ : Sort w} (f : DHashMap α β → γ) (h : ∀ a b, a ~m b → f a = f b) (m : ExtDHashMap α β) : γ :=
73+ m.1 .lift f h
74+
75+ /-- Internal implementation detail of the hash map. -/
76+ abbrev pliftOn {γ : Sort w} (m : ExtDHashMap α β) (f : (a : DHashMap α β) → m = mk a → γ)
77+ (h : ∀ a b h₁ h₂, a ~m b → f a h₁ = f b h₂) : γ :=
78+ m.1 .pliftOn (fun a ha => f a (by cases m; cases ha; rfl)) (fun _ _ _ _ h' => h _ _ _ _ h')
79+
80+ @[induction_eliminator, cases_eliminator, elab_as_elim]
81+ theorem inductionOn {motive : ExtDHashMap α β → Prop } (m : ExtDHashMap α β)
82+ (mk : (a : DHashMap α β) → motive (mk a)) : motive m :=
83+ (m.1 .inductionOn fun _ => mk _ : motive ⟨m.1 ⟩)
84+
85+ @[elab_as_elim]
86+ theorem inductionOn₂ {motive : ExtDHashMap α β → ExtDHashMap α β → Prop }
87+ (m₁ m₂ : ExtDHashMap α β) (mk : (a b : DHashMap α β) → motive (mk a) (mk b)) : motive m₁ m₂ :=
88+ m₁.inductionOn fun _ => m₂.inductionOn fun _ => mk _ _
89+
90+ theorem sound {m₁ m₂ : DHashMap α β} (h : m₁ ~m m₂) : mk m₁ = mk m₂ :=
91+ congrArg mk' (Quotient.sound h)
92+
93+ theorem exact {m₁ m₂ : DHashMap α β} (h : mk m₁ = mk m₂) : m₁ ~m m₂ :=
94+ Quotient.exact (congrArg inner h)
95+
6496@[inline, inherit_doc DHashMap.emptyWithCapacity]
6597def emptyWithCapacity [BEq α] [Hashable α]
6698 (capacity := 8 ) : ExtDHashMap α β :=
67- Quotient.mk' (DHashMap.emptyWithCapacity capacity)
99+ mk (DHashMap.emptyWithCapacity capacity)
68100
69101instance [BEq α] [Hashable α] : EmptyCollection (ExtDHashMap α β) where
70102 emptyCollection := emptyWithCapacity
@@ -75,8 +107,8 @@ instance [BEq α] [Hashable α] : Inhabited (ExtDHashMap α β) where
75107@[inline, inherit_doc DHashMap.insert]
76108def insert [EquivBEq α] [LawfulHashable α] (m : ExtDHashMap α β) (a : α)
77109 (b : β a) : ExtDHashMap α β :=
78- m.lift (fun m => Quotient.mk' (m.insert a b))
79- (fun m m' (h : m ~m m') => Quotient. sound (h.insert a b))
110+ m.lift (fun m => mk (m.insert a b))
111+ (fun m m' (h : m ~m m') => sound (h.insert a b))
80112
81113instance [EquivBEq α] [LawfulHashable α] : Singleton ((a : α) × β a) (ExtDHashMap α β) where
82114 singleton | ⟨a, b⟩ => (∅ : ExtDHashMap α β).insert a b
@@ -90,37 +122,37 @@ instance [EquivBEq α] [LawfulHashable α] : LawfulSingleton ((a : α) × β a)
90122@[inline, inherit_doc DHashMap.insertIfNew]
91123def insertIfNew [EquivBEq α] [LawfulHashable α] (m : ExtDHashMap α β)
92124 (a : α) (b : β a) : ExtDHashMap α β :=
93- m.lift (fun m => Quotient.mk' (m.insertIfNew a b))
94- (fun m m' (h : m ~m m') => Quotient. sound (h.insertIfNew a b))
125+ m.lift (fun m => mk (m.insertIfNew a b))
126+ (fun m m' (h : m ~m m') => sound (h.insertIfNew a b))
95127
96128@[inline, inherit_doc DHashMap.containsThenInsert]
97129def containsThenInsert [EquivBEq α] [LawfulHashable α]
98130 (m : ExtDHashMap α β) (a : α) (b : β a) : Bool × ExtDHashMap α β :=
99- m.lift (fun m => let m' := m.containsThenInsert a b; ⟨m'.1 , Quotient.mk' m'.2 ⟩)
131+ m.lift (fun m => let m' := m.containsThenInsert a b; ⟨m'.1 , mk m'.2 ⟩)
100132 (fun m m' (h : m ~m m') =>
101133 Prod.ext
102134 (m.containsThenInsert_fst.symm ▸ m'.containsThenInsert_fst.symm ▸ h.contains_eq)
103- (Quotient. sound <|
135+ (sound <|
104136 m.containsThenInsert_snd.symm ▸ m'.containsThenInsert_snd.symm ▸ h.insert a b))
105137
106138@[inline, inherit_doc DHashMap.containsThenInsertIfNew]
107139def containsThenInsertIfNew [EquivBEq α] [LawfulHashable α]
108140 (m : ExtDHashMap α β) (a : α) (b : β a) : Bool × ExtDHashMap α β :=
109- m.lift (fun m => let m' := m.containsThenInsertIfNew a b; ⟨m'.1 , Quotient.mk' m'.2 ⟩)
141+ m.lift (fun m => let m' := m.containsThenInsertIfNew a b; ⟨m'.1 , mk m'.2 ⟩)
110142 (fun m m' (h : m ~m m') =>
111143 Prod.ext
112144 (m.containsThenInsertIfNew_fst.symm ▸ m'.containsThenInsertIfNew_fst.symm ▸ h.contains_eq)
113- (Quotient. sound <|
145+ (sound <|
114146 m.containsThenInsertIfNew_snd.symm ▸ m'.containsThenInsertIfNew_snd.symm ▸ h.insertIfNew a b))
115147
116148@[inline, inherit_doc DHashMap.getThenInsertIfNew?]
117149def getThenInsertIfNew? [LawfulBEq α]
118150 (m : ExtDHashMap α β) (a : α) (b : β a) : Option (β a) × ExtDHashMap α β :=
119- m.lift (fun m => let m' := m.getThenInsertIfNew? a b; ⟨m'.1 , Quotient.mk' m'.2 ⟩)
151+ m.lift (fun m => let m' := m.getThenInsertIfNew? a b; ⟨m'.1 , mk m'.2 ⟩)
120152 (fun m m' (h : m ~m m') =>
121153 Prod.ext
122154 (m.getThenInsertIfNew?_fst.symm ▸ m'.getThenInsertIfNew?_fst.symm ▸ h.get?_eq)
123- (Quotient. sound <|
155+ (sound <|
124156 m.getThenInsertIfNew?_snd.symm ▸ m'.getThenInsertIfNew?_snd.symm ▸ h.insertIfNew a b))
125157
126158@[inline, inherit_doc DHashMap.get?]
@@ -158,8 +190,8 @@ def getD [LawfulBEq α] (m : ExtDHashMap α β)
158190@[inline, inherit_doc DHashMap.erase]
159191def erase [EquivBEq α] [LawfulHashable α] (m : ExtDHashMap α β) (a : α) :
160192 ExtDHashMap α β :=
161- m.lift (fun m => Quotient.mk' (m.erase a))
162- (fun m m' (h : m ~m m') => Quotient. sound (h.erase a))
193+ m.lift (fun m => mk (m.erase a))
194+ (fun m m' (h : m ~m m') => sound (h.erase a))
163195
164196namespace Const
165197
@@ -195,12 +227,12 @@ def getThenInsertIfNew? [EquivBEq α] [LawfulHashable α]
195227 Option β × ExtDHashMap α (fun _ => β) :=
196228 m.lift (fun m =>
197229 let m' := DHashMap.Const.getThenInsertIfNew? m a b
198- ⟨m'.1 , Quotient.mk' m'.2 ⟩)
230+ ⟨m'.1 , mk m'.2 ⟩)
199231 (fun m m' (h : m ~m m') =>
200232 Prod.ext
201233 (DHashMap.Const.getThenInsertIfNew?_fst.symm ▸
202234 DHashMap.Const.getThenInsertIfNew?_fst.symm ▸ h.constGet?_eq)
203- (Quotient. sound <|
235+ (sound <|
204236 DHashMap.Const.getThenInsertIfNew?_snd.symm ▸
205237 DHashMap.Const.getThenInsertIfNew?_snd.symm ▸ h.insertIfNew a b))
206238
@@ -237,44 +269,44 @@ def isEmpty [EquivBEq α] [LawfulHashable α] (m : ExtDHashMap α β) : Bool :=
237269@[inline, inherit_doc DHashMap.filter]
238270def filter [EquivBEq α] [LawfulHashable α] (f : (a : α) → β a → Bool)
239271 (m : ExtDHashMap α β) : ExtDHashMap α β :=
240- m.lift (fun m => Quotient.mk' (m.filter f))
241- (fun m m' (h : m ~m m') => Quotient. sound (h.filter f))
272+ m.lift (fun m => mk (m.filter f))
273+ (fun m m' (h : m ~m m') => sound (h.filter f))
242274
243275@[inline, inherit_doc DHashMap.map]
244276def map [EquivBEq α] [LawfulHashable α] (f : (a : α) → β a → γ a)
245277 (m : ExtDHashMap α β) : ExtDHashMap α γ :=
246- m.lift (fun m => Quotient.mk' (m.map f))
247- (fun m m' (h : m ~m m') => Quotient. sound (h.map f))
278+ m.lift (fun m => mk (m.map f))
279+ (fun m m' (h : m ~m m') => sound (h.map f))
248280
249281@[inline, inherit_doc DHashMap.filterMap]
250282def filterMap [EquivBEq α] [LawfulHashable α] (f : (a : α) → β a → Option (γ a))
251283 (m : ExtDHashMap α β) : ExtDHashMap α γ :=
252- m.lift (fun m => Quotient.mk' (m.filterMap f))
253- (fun m m' (h : m ~m m') => Quotient. sound (h.filterMap f))
284+ m.lift (fun m => mk (m.filterMap f))
285+ (fun m m' (h : m ~m m') => sound (h.filterMap f))
254286
255287@[inline, inherit_doc DHashMap.modify]
256288def modify [LawfulBEq α] (m : ExtDHashMap α β)
257289 (a : α) (f : β a → β a) : ExtDHashMap α β :=
258- m.lift (fun m => Quotient.mk' (m.modify a f))
259- (fun m m' (h : m ~m m') => Quotient. sound (h.modify a f))
290+ m.lift (fun m => mk (m.modify a f))
291+ (fun m m' (h : m ~m m') => sound (h.modify a f))
260292
261293@[inline, inherit_doc DHashMap.Const.modify]
262294def Const.modify [EquivBEq α] [LawfulHashable α] {β : Type v} (m : ExtDHashMap α (fun _ => β))
263295 (a : α) (f : β → β) : ExtDHashMap α (fun _ => β) :=
264- m.lift (fun m => Quotient.mk' (DHashMap.Const.modify m a f))
265- (fun m m' (h : m ~m m') => Quotient. sound (h.constModify a f))
296+ m.lift (fun m => mk (DHashMap.Const.modify m a f))
297+ (fun m m' (h : m ~m m') => sound (h.constModify a f))
266298
267299@[inline, inherit_doc DHashMap.alter]
268300def alter [LawfulBEq α] (m : ExtDHashMap α β)
269301 (a : α) (f : Option (β a) → Option (β a)) : ExtDHashMap α β :=
270- m.lift (fun m => Quotient.mk' (m.alter a f))
271- (fun m m' (h : m ~m m') => Quotient. sound (h.alter a f))
302+ m.lift (fun m => mk (m.alter a f))
303+ (fun m m' (h : m ~m m') => sound (h.alter a f))
272304
273305@[inline, inherit_doc DHashMap.Const.alter]
274306def Const.alter [EquivBEq α] [LawfulHashable α] {β : Type v} (m : ExtDHashMap α (fun _ => β))
275307 (a : α) (f : Option β → Option β) : ExtDHashMap α (fun _ => β) :=
276- m.lift (fun m => Quotient.mk' (DHashMap.Const.alter m a f))
277- (fun m m' (h : m ~m m') => Quotient. sound (h.constAlter a f))
308+ m.lift (fun m => mk (DHashMap.Const.alter m a f))
309+ (fun m m' (h : m ~m m') => sound (h.constAlter a f))
278310
279311/-
280312Note: We can't use the existing functions because weird (noncomputable) `ForIn` instances
@@ -315,22 +347,22 @@ def Const.insertManyIfNewUnit [EquivBEq α] [LawfulHashable α] {ρ : Type w}
315347@[inline, inherit_doc DHashMap.Const.unitOfArray]
316348def Const.unitOfArray [BEq α] [Hashable α] (l : Array α) :
317349 ExtDHashMap α (fun _ => Unit) :=
318- Quotient.mk' (DHashMap.Const.unitOfArray l)
350+ mk (DHashMap.Const.unitOfArray l)
319351
320352@[inline, inherit_doc DHashMap.ofList]
321353def ofList [BEq α] [Hashable α] (l : List ((a : α) × β a)) :
322354 ExtDHashMap α β :=
323- Quotient.mk' (DHashMap.ofList l)
355+ mk (DHashMap.ofList l)
324356
325357@[inline, inherit_doc DHashMap.Const.ofList]
326358def Const.ofList {β : Type v} [BEq α] [Hashable α] (l : List (α × β)) :
327359 ExtDHashMap α (fun _ => β) :=
328- Quotient.mk' (DHashMap.Const.ofList l)
360+ mk (DHashMap.Const.ofList l)
329361
330362@[inline, inherit_doc DHashMap.Const.unitOfList]
331363def Const.unitOfList [BEq α] [Hashable α] (l : List α) :
332364 ExtDHashMap α (fun _ => Unit) :=
333- Quotient.mk' (DHashMap.Const.unitOfList l)
365+ mk (DHashMap.Const.unitOfList l)
334366
335367end ExtDHashMap
336368
0 commit comments