File: .lake/packages/batteries/Batteries/Data/HashMap/Basic.lean

full_name: Batteries.HashMap.LawfulHashable.hash_eq
code: /-- A hash is lawful if elements which compare equal under `==` have equal hash. -/
class LawfulHashable (α : Type _) [BEq α] [Hashable α] : Prop where
  /-- Two elements which compare equal under the `BEq` instance have equal hash. -/
  hash_eq {a b : α} : a == b → hash a = hash b
goal: (a == b) = true → hash a = hash b

full_name: Batteries.HashMap.LawfulHashable
code: /-- A hash is lawful if elements which compare equal under `==` have equal hash. -/
class LawfulHashable (α : Type _) [BEq α] [Hashable α] : Prop where
  /-- Two elements which compare equal under the `BEq` instance have equal hash. -/
  hash_eq {a b : α} : a == b → hash a = hash b
goal: Prop

full_name: Batteries.HashMap.Imp.Buckets
code: /--
The bucket array of a `HashMap` is a nonempty array of `AssocList`s.
(This type is an internal implementation detail of `HashMap`.)
-/
def Buckets (α : Type u) (β : Type v) 
goal: Type (max 0 u v)

full_name: Batteries.HashMap.Imp.Buckets.mk
code: /-- Construct a new empty bucket array with the specified capacity. -/
def mk (buckets := 8) (h : 0 < buckets := by decide) : Buckets α β 
goal: Batteries.HashMap.Imp.Buckets α β

full_name: Batteries.HashMap.Imp.Buckets.update
code: /-- Update one bucket in the bucket array with a new value. -/
def update (data : Buckets α β) (i : USize)
    (d : AssocList α β) (h : i.toNat < data.1.size) : Buckets α β 
goal: Batteries.HashMap.Imp.Buckets α β

full_name: Batteries.HashMap.Imp.Buckets.size
code: /--
The number of elements in the bucket array.
Note: this is marked `noncomputable` because it is only intended for specification.
-/
noncomputable def size (data : Buckets α β) : Nat 
goal: Nat

full_name: Batteries.HashMap.Imp.Buckets.update_size
code: @[simp] theorem update_size (self : Buckets α β) (i d h) :
    (self.update i d h).1.size = self.1.size 
goal: (self.update i d h).val.size = self.val.size

full_name: Batteries.HashMap.Imp.Buckets.mapVal
code: /-- Map a function over the values in the map. -/
@[specialize] def mapVal (f : α → β → γ) (self : Buckets α β) : Buckets α γ 
goal: Batteries.HashMap.Imp.Buckets α γ

full_name: Batteries.HashMap.Imp.Buckets.WF.distinct
code: /--
The well-formedness invariant for the bucket array says that every element hashes to its index
(assuming the hash is lawful - otherwise there are no promises about where elements are located).
-/
structure WF [BEq α] [Hashable α] (buckets : Buckets α β) : Prop where
  /-- The elements of a bucket are all distinct according to the `BEq` relation. -/
  distinct [LawfulHashable α] [PartialEquivBEq α] : ∀ bucket ∈ buckets.1.data,
    bucket.toList.Pairwise fun a b => ¬(a.1 == b.1)
  /-- Every element in a bucket should hash to its location. -/
  hash_self (i : Nat) (h : i < buckets.1.size) :
    buckets.1[i].All fun k _ => ((hash k).toUSize % buckets.1.size).toNat = i
goal: bucket ∈ buckets.val.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) bucket.toList

full_name: Batteries.HashMap.Imp.Buckets.WF
code: /--
The well-formedness invariant for the bucket array says that every element hashes to its index
(assuming the hash is lawful - otherwise there are no promises about where elements are located).
-/
structure WF [BEq α] [Hashable α] (buckets : Buckets α β) : Prop where
  /-- The elements of a bucket are all distinct according to the `BEq` relation. -/
  distinct [LawfulHashable α] [PartialEquivBEq α] : ∀ bucket ∈ buckets.1.data,
    bucket.toList.Pairwise fun a b => ¬(a.1 == b.1)
  /-- Every element in a bucket should hash to its location. -/
  hash_self (i : Nat) (h : i < buckets.1.size) :
    buckets.1[i].All fun k _ => ((hash k).toUSize % buckets.1.size).toNat = i
goal: Prop

full_name: Batteries.HashMap.Imp.Buckets.WF.hash_self
code: /--
The well-formedness invariant for the bucket array says that every element hashes to its index
(assuming the hash is lawful - otherwise there are no promises about where elements are located).
-/
structure WF [BEq α] [Hashable α] (buckets : Buckets α β) : Prop where
  /-- The elements of a bucket are all distinct according to the `BEq` relation. -/
  distinct [LawfulHashable α] [PartialEquivBEq α] : ∀ bucket ∈ buckets.1.data,
    bucket.toList.Pairwise fun a b => ¬(a.1 == b.1)
  /-- Every element in a bucket should hash to its location. -/
  hash_self (i : Nat) (h : i < buckets.1.size) :
    buckets.1[i].All fun k _ => ((hash k).toUSize % buckets.1.size).toNat = i
goal: Batteries.AssocList.All (fun k x => ((hash k).toUSize % buckets.val.size).toNat = i) buckets.val[i]

full_name: Batteries.HashMap.Imp.size
code: /-- `HashMap.Imp α β` is the internal implementation type of `HashMap α β`. -/
structure Imp (α : Type u) (β : Type v) where
  /-- The number of elements stored in the `HashMap`.
  We cache this both so that we can implement `.size` in `O(1)`, and also because we
  use the size to determine when to resize the map. -/
  size    : Nat
  /-- The bucket array of the `HashMap`. -/
  buckets : Imp.Buckets α β
goal: Nat

full_name: Batteries.HashMap.Imp
code: /-- `HashMap.Imp α β` is the internal implementation type of `HashMap α β`. -/
structure Imp (α : Type u) (β : Type v) where
  /-- The number of elements stored in the `HashMap`.
  We cache this both so that we can implement `.size` in `O(1)`, and also because we
  use the size to determine when to resize the map. -/
  size    : Nat
  /-- The bucket array of the `HashMap`. -/
  buckets : Imp.Buckets α β
goal: Type (max u v)

full_name: Batteries.HashMap.Imp.buckets
code: /-- `HashMap.Imp α β` is the internal implementation type of `HashMap α β`. -/
structure Imp (α : Type u) (β : Type v) where
  /-- The number of elements stored in the `HashMap`.
  We cache this both so that we can implement `.size` in `O(1)`, and also because we
  use the size to determine when to resize the map. -/
  size    : Nat
  /-- The bucket array of the `HashMap`. -/
  buckets : Imp.Buckets α β
goal: Batteries.HashMap.Imp.Buckets α β

full_name: Batteries.HashMap.Imp.numBucketsForCapacity
code: /--
Given a desired capacity, this returns the number of buckets we should reserve.
A "load factor" of 0.75 is the usual standard for hash maps, so we return `capacity * 4 / 3`.
-/
@[inline] def numBucketsForCapacity (capacity : Nat) : Nat 
goal: Nat

full_name: Batteries.HashMap.Imp.empty'
code: /-- Constructs an empty hash map with the specified nonzero number of buckets. -/
@[inline] def empty' (buckets := 8) (h : 0 < buckets := by decide) : Imp α β 
goal: Batteries.HashMap.Imp α β

full_name: Batteries.HashMap.Imp.empty
code: /-- Constructs an empty hash map with the specified target capacity. -/
def empty (capacity := 0) : Imp α β 
goal: Batteries.HashMap.Imp α β

full_name: Batteries.HashMap.Imp.mkIdx
code: /-- Calculates the bucket index from a hash value `u`. -/
def mkIdx {n : Nat} (h : 0 < n) (u : USize) : {u : USize // u.toNat < n} 
goal: { u // u.toNat < n }

full_name: Batteries.HashMap.Imp.reinsertAux
code: /--
Inserts a key-value pair into the bucket array. This function assumes that the data is not
already in the array, which is appropriate when reinserting elements into the array after a resize.
-/
@[inline] def reinsertAux [Hashable α]
    (data : Buckets α β) (a : α) (b : β) : Buckets α β 
goal: Batteries.HashMap.Imp.Buckets α β

full_name: Batteries.HashMap.Imp.foldM
code: /-- Folds a monadic function over the elements in the map (in arbitrary order). -/
@[inline] def foldM [Monad m] (f : δ → α → β → m δ) (d : δ) (map : Imp α β) : m δ 
goal: m δ

full_name: Batteries.HashMap.Imp.fold
code: /-- Folds a function over the elements in the map (in arbitrary order). -/
@[inline] def fold (f : δ → α → β → δ) (d : δ) (m : Imp α β) : δ 
goal: δ

full_name: Batteries.HashMap.Imp.forM
code: /-- Runs a monadic function over the elements in the map (in arbitrary order). -/
@[inline] def forM [Monad m] (f : α → β → m PUnit) (h : Imp α β) : m PUnit 
goal: m PUnit

full_name: Batteries.HashMap.Imp.findEntry?
code: /-- Given a key `a`, returns a key-value pair in the map whose key compares equal to `a`. -/
def findEntry? [BEq α] [Hashable α] (m : Imp α β) (a : α) : Option (α × β) 
goal: Option (α × β)

full_name: Batteries.HashMap.Imp.find?
code: /-- Looks up an element in the map with key `a`. -/
def find? [BEq α] [Hashable α] (m : Imp α β) (a : α) : Option β 
goal: Option β

full_name: Batteries.HashMap.Imp.contains
code: /-- Returns true if the element `a` is in the map. -/
def contains [BEq α] [Hashable α] (m : Imp α β) (a : α) : Bool 
goal: Bool

full_name: Batteries.HashMap.Imp.expand
code: /-- Copies all the entries from `buckets` into a new hash map with a larger capacity. -/
def expand [Hashable α] (size : Nat) (buckets : Buckets α β) : Imp α β 
goal: Batteries.HashMap.Imp α β

full_name: Batteries.HashMap.Imp.expand.go
code: /-- Copies all the entries from `buckets` into a new hash map with a larger capacity. -/
def expand [Hashable α] (size : Nat) (buckets : Buckets α β) : Imp α β 
goal: Batteries.HashMap.Imp.Buckets α β

full_name: Batteries.HashMap.Imp.insert
code: /--
Inserts key-value pair `a, b` into the map.
If an element equal to `a` is already in the map, it is replaced by `b`.
-/
@[inline] def insert [BEq α] [Hashable α] (m : Imp α β) (a : α) (b : β) : Imp α β 
goal: Batteries.HashMap.Imp α β

full_name: Batteries.HashMap.Imp.erase
code: /--
Removes key `a` from the map. If it does not exist in the map, the map is returned unchanged.
-/
def erase [BEq α] [Hashable α] (m : Imp α β) (a : α) : Imp α β 
goal: Batteries.HashMap.Imp α β

full_name: Batteries.HashMap.Imp.mapVal
code: /-- Map a function over the values in the map. -/
@[inline] def mapVal (f : α → β → γ) (self : Imp α β) : Imp α γ 
goal: Batteries.HashMap.Imp α γ

full_name: Batteries.HashMap.Imp.modify
code: /-- Performs an in-place edit of the value, ensuring that the value is used linearly. -/
def modify [BEq α] [Hashable α] (m : Imp α β) (a : α) (f : α → β → β) : Imp α β 
goal: Batteries.HashMap.Imp α β

full_name: Batteries.HashMap.Imp.filterMap.go
code: /--
Applies `f` to each key-value pair `a, b` in the map. If it returns `some c` then
`a, c` is pushed into the new map; else the key is removed from the map.
-/
@[specialize] def filterMap {α : Type u} {β : Type v} {γ : Type w}
    (f : α → β → Option γ) (m : Imp α β) : Imp α γ 
goal: Batteries.AssocList α β → ULift Nat → Batteries.AssocList α γ × ULift Nat

full_name: Batteries.HashMap.Imp.filterMap
code: /--
Applies `f` to each key-value pair `a, b` in the map. If it returns `some c` then
`a, c` is pushed into the new map; else the key is removed from the map.
-/
@[specialize] def filterMap {α : Type u} {β : Type v} {γ : Type w}
    (f : α → β → Option γ) (m : Imp α β) : Imp α γ 
goal: Batteries.HashMap.Imp α γ

full_name: Batteries.HashMap.Imp.filter
code: /-- Constructs a map with the set of all pairs `a, b` such that `f` returns true. -/
@[inline] def filter (f : α → β → Bool) (m : Imp α β) : Imp α β 
goal: Batteries.HashMap.Imp α β

full_name: Batteries.HashMap.Imp.WF
code: /--
The well-formedness invariant for a hash map. The first constructor is the real invariant,
and the others allow us to "cheat" in this file and define `insert` and `erase`,
which have more complex proofs that are delayed to `Batteries.Data.HashMap.Lemmas`.
-/
inductive WF [BEq α] [Hashable α] : Imp α β → Prop where
  /-- The real well-formedness invariant:
  * The `size` field should match the actual number of elements in the map
  * The bucket array should be well-formed, meaning that if the hashable instance
    is lawful then every element hashes to its index. -/
  | mk : m.size = m.buckets.size → m.buckets.WF → WF m
  /-- The empty hash map is well formed. -/
  | empty' : WF (empty' n h)
  /-- Inserting into a well formed hash map yields a well formed hash map. -/
  | insert : WF m → WF (insert m a b)
  /-- Removing an element from a well formed hash map yields a well formed hash map. -/
  | erase : WF m → WF (erase m a)
  /-- Replacing an element in a well formed hash map yields a well formed hash map. -/
  | modify : WF m → WF (modify m a f)
goal: Batteries.HashMap.Imp α β → Prop

full_name: Batteries.HashMap.Imp.WF.insert
code: /--
The well-formedness invariant for a hash map. The first constructor is the real invariant,
and the others allow us to "cheat" in this file and define `insert` and `erase`,
which have more complex proofs that are delayed to `Batteries.Data.HashMap.Lemmas`.
-/
inductive WF [BEq α] [Hashable α] : Imp α β → Prop where
  /-- The real well-formedness invariant:
  * The `size` field should match the actual number of elements in the map
  * The bucket array should be well-formed, meaning that if the hashable instance
    is lawful then every element hashes to its index. -/
  | mk : m.size = m.buckets.size → m.buckets.WF → WF m
  /-- The empty hash map is well formed. -/
  | empty' : WF (empty' n h)
  /-- Inserting into a well formed hash map yields a well formed hash map. -/
  | insert : WF m → WF (insert m a b)
  /-- Removing an element from a well formed hash map yields a well formed hash map. -/
  | erase : WF m → WF (erase m a)
  /-- Replacing an element in a well formed hash map yields a well formed hash map. -/
  | modify : WF m → WF (modify m a f)
goal: ∀ {x : Type u_2} {m : Batteries.HashMap.Imp α x} {a : α} {b : x}, m.WF → (m.insert a b).WF

full_name: Batteries.HashMap.Imp.WF.modify
code: /--
The well-formedness invariant for a hash map. The first constructor is the real invariant,
and the others allow us to "cheat" in this file and define `insert` and `erase`,
which have more complex proofs that are delayed to `Batteries.Data.HashMap.Lemmas`.
-/
inductive WF [BEq α] [Hashable α] : Imp α β → Prop where
  /-- The real well-formedness invariant:
  * The `size` field should match the actual number of elements in the map
  * The bucket array should be well-formed, meaning that if the hashable instance
    is lawful then every element hashes to its index. -/
  | mk : m.size = m.buckets.size → m.buckets.WF → WF m
  /-- The empty hash map is well formed. -/
  | empty' : WF (empty' n h)
  /-- Inserting into a well formed hash map yields a well formed hash map. -/
  | insert : WF m → WF (insert m a b)
  /-- Removing an element from a well formed hash map yields a well formed hash map. -/
  | erase : WF m → WF (erase m a)
  /-- Replacing an element in a well formed hash map yields a well formed hash map. -/
  | modify : WF m → WF (modify m a f)
goal: ∀ {x : Type u_2} {m : Batteries.HashMap.Imp α x} {a : α} {f : α → x → x}, m.WF → (m.modify a f).WF

full_name: Batteries.HashMap.Imp.WF.erase
code: /--
The well-formedness invariant for a hash map. The first constructor is the real invariant,
and the others allow us to "cheat" in this file and define `insert` and `erase`,
which have more complex proofs that are delayed to `Batteries.Data.HashMap.Lemmas`.
-/
inductive WF [BEq α] [Hashable α] : Imp α β → Prop where
  /-- The real well-formedness invariant:
  * The `size` field should match the actual number of elements in the map
  * The bucket array should be well-formed, meaning that if the hashable instance
    is lawful then every element hashes to its index. -/
  | mk : m.size = m.buckets.size → m.buckets.WF → WF m
  /-- The empty hash map is well formed. -/
  | empty' : WF (empty' n h)
  /-- Inserting into a well formed hash map yields a well formed hash map. -/
  | insert : WF m → WF (insert m a b)
  /-- Removing an element from a well formed hash map yields a well formed hash map. -/
  | erase : WF m → WF (erase m a)
  /-- Replacing an element in a well formed hash map yields a well formed hash map. -/
  | modify : WF m → WF (modify m a f)
goal: ∀ {x : Type u_2} {m : Batteries.HashMap.Imp α x} {a : α}, m.WF → (m.erase a).WF

full_name: Batteries.HashMap.Imp.WF.empty'
code: /--
The well-formedness invariant for a hash map. The first constructor is the real invariant,
and the others allow us to "cheat" in this file and define `insert` and `erase`,
which have more complex proofs that are delayed to `Batteries.Data.HashMap.Lemmas`.
-/
inductive WF [BEq α] [Hashable α] : Imp α β → Prop where
  /-- The real well-formedness invariant:
  * The `size` field should match the actual number of elements in the map
  * The bucket array should be well-formed, meaning that if the hashable instance
    is lawful then every element hashes to its index. -/
  | mk : m.size = m.buckets.size → m.buckets.WF → WF m
  /-- The empty hash map is well formed. -/
  | empty' : WF (empty' n h)
  /-- Inserting into a well formed hash map yields a well formed hash map. -/
  | insert : WF m → WF (insert m a b)
  /-- Removing an element from a well formed hash map yields a well formed hash map. -/
  | erase : WF m → WF (erase m a)
  /-- Replacing an element in a well formed hash map yields a well formed hash map. -/
  | modify : WF m → WF (modify m a f)
goal: ∀ {x : Type u_2} {n : Nat} {h : 0 < n}, (Batteries.HashMap.Imp.empty' n h).WF

full_name: Batteries.HashMap.Imp.WF.mk
code: /--
The well-formedness invariant for a hash map. The first constructor is the real invariant,
and the others allow us to "cheat" in this file and define `insert` and `erase`,
which have more complex proofs that are delayed to `Batteries.Data.HashMap.Lemmas`.
-/
inductive WF [BEq α] [Hashable α] : Imp α β → Prop where
  /-- The real well-formedness invariant:
  * The `size` field should match the actual number of elements in the map
  * The bucket array should be well-formed, meaning that if the hashable instance
    is lawful then every element hashes to its index. -/
  | mk : m.size = m.buckets.size → m.buckets.WF → WF m
  /-- The empty hash map is well formed. -/
  | empty' : WF (empty' n h)
  /-- Inserting into a well formed hash map yields a well formed hash map. -/
  | insert : WF m → WF (insert m a b)
  /-- Removing an element from a well formed hash map yields a well formed hash map. -/
  | erase : WF m → WF (erase m a)
  /-- Replacing an element in a well formed hash map yields a well formed hash map. -/
  | modify : WF m → WF (modify m a f)
goal: ∀ {x : Type u_2} {m : Batteries.HashMap.Imp α x}, m.size = m.buckets.size → m.buckets.WF → m.WF

full_name: Batteries.HashMap.Imp.WF.empty
code: theorem WF.empty [BEq α] [Hashable α] : WF (empty n : Imp α β) 
goal: (Batteries.HashMap.Imp.empty n).WF

full_name: Batteries.HashMap
code: /--
`HashMap α β` is a key-value map which stores elements in an array using a hash function
to find the values. This allows it to have very good performance for lookups
(average `O(1)` for a perfectly random hash function), but it is not a persistent data structure,
meaning that one should take care to use the map linearly when performing updates.
Copies are `O(n)`.
-/
def _root_.Batteries.HashMap (α : Type u) (β : Type v) [BEq α] [Hashable α] 
goal: Type (max 0 u v)

full_name: Batteries.mkHashMap
code: /-- Make a new hash map with the specified capacity. -/
@[inline] def _root_.Batteries.mkHashMap [BEq α] [Hashable α] (capacity := 0) : HashMap α β 
goal: Batteries.HashMap α β

full_name: Batteries.HashMap.instInhabited
code: instance [BEq α] [Hashable α] : Inhabited (HashMap α β) 
goal: Inhabited (Batteries.HashMap α β)

full_name: Batteries.HashMap.instEmptyCollection
code: instance [BEq α] [Hashable α] : EmptyCollection (HashMap α β) 
goal: EmptyCollection (Batteries.HashMap α β)

full_name: Batteries.HashMap.empty
code: /--
Make a new empty hash map.
```
(empty : Batteries.HashMap Int Int).toList = []
```
-/
@[inline] def empty [BEq α] [Hashable α] : HashMap α β 
goal: Batteries.HashMap α β

full_name: Batteries.HashMap.size
code: /--
The number of elements in the hash map.
```
(ofList [("one", 1), ("two", 2)]).size = 2
```
-/
@[inline] def size (self : HashMap α β) : Nat 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → Nat

full_name: Batteries.HashMap.isEmpty
code: /--
Is the map empty?
```
(empty : Batteries.HashMap Int Int).isEmpty = true
(ofList [("one", 1), ("two", 2)]).isEmpty = false
```
-/
@[inline] def isEmpty (self : HashMap α β) : Bool 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → Bool

full_name: Batteries.HashMap.insert
code: /--
Inserts key-value pair `a, b` into the map.
If an element equal to `a` is already in the map, it is replaced by `b`.
```
def hashMap := ofList [("one", 1), ("two", 2)]
hashMap.insert "three" 3 = {"one" => 1, "two" => 2, "three" => 3}
hashMap.insert "two" 0 = {"one" => 1, "two" => 0}
```
-/
def insert (self : HashMap α β) (a : α) (b : β) : HashMap α β 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → α → β → Batteries.HashMap α β

full_name: Batteries.HashMap.insert'
code: /--
Similar to `insert`, but also returns a boolean flag indicating whether an existing entry has been
replaced with `a => b`.
```
def hashMap := ofList [("one", 1), ("two", 2)]
hashMap.insert' "three" 3 = ({"one" => 1, "two" => 2, "three" => 3}, false)
hashMap.insert' "two" 0 = ({"one" => 1, "two" => 0}, true)
```
-/
@[inline] def insert' (m : HashMap α β) (a : α) (b : β) : HashMap α β × Bool 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → α → β → Batteries.HashMap α β × Bool

full_name: Batteries.HashMap.erase
code: /--
Removes key `a` from the map. If it does not exist in the map, the map is returned unchanged.
```
def hashMap := ofList [("one", 1), ("two", 2)]
hashMap.erase "one" = {"two" => 2}
hashMap.erase "three" = {"one" => 1, "two" => 2}
```
-/
@[inline] def erase (self : HashMap α β) (a : α) : HashMap α β 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → α → Batteries.HashMap α β

full_name: Batteries.HashMap.modify
code: /--
Performs an in-place edit of the value, ensuring that the value is used linearly.
The function `f` is passed the original key of the entry, along with the value in the map.
```
(ofList [("one", 1), ("two", 2)]).modify "one" (fun _ v => v + 1) = {"one" => 2, "two" => 2}
(ofList [("one", 1), ("two", 2)]).modify "three" (fun _ v => v + 1) = {"one" => 1, "two" => 2}
```
-/
def modify (self : HashMap α β) (a : α) (f : α → β → β) : HashMap α β 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → α → (α → β → β) → Batteries.HashMap α β

full_name: Batteries.HashMap.findEntry?
code: /--
Given a key `a`, returns a key-value pair in the map whose key compares equal to `a`.
Note that the returned key may not be identical to the input, if `==` ignores some part
of the value.
```
def hashMap := ofList [("one", 1), ("two", 2)]
hashMap.findEntry? "one" = some ("one", 1)
hashMap.findEntry? "three" = none
```
-/
@[inline] def findEntry? (self : HashMap α β) (a : α) : Option (α × β) 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → α → Option (α × β)

full_name: Batteries.HashMap.find?
code: /--
Looks up an element in the map with key `a`.
```
def hashMap := ofList [("one", 1), ("two", 2)]
hashMap.find? "one" = some 1
hashMap.find? "three" = none
```
-/
@[inline] def find? (self : HashMap α β) (a : α) : Option β 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → α → Option β

full_name: Batteries.HashMap.findD
code: /--
Looks up an element in the map with key `a`. Returns `b₀` if the element is not found.
```
def hashMap := ofList [("one", 1), ("two", 2)]
hashMap.findD "one" 0 = 1
hashMap.findD "three" 0 = 0
```
-/
@[inline] def findD (self : HashMap α β) (a : α) (b₀ : β) : β 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → α → β → β

full_name: Batteries.HashMap.find!
code: /--
Looks up an element in the map with key `a`. Panics if the element is not found.
```
def hashMap := ofList [("one", 1), ("two", 2)]
hashMap.find! "one" = 1
hashMap.find! "three" => panic!
```
-/
@[inline] def find! [Inhabited β] (self : HashMap α β) (a : α) : β 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → [inst : Inhabited β] → Batteries.HashMap α β → α → β

full_name: Batteries.HashMap.instGetElemOptionTrue
code: instance : GetElem (HashMap α β) α (Option β) fun _ _ => True 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → GetElem (Batteries.HashMap α β) α (Option β) fun x x => True

full_name: Batteries.HashMap.contains
code: /--
Returns true if the element `a` is in the map.
```
def hashMap := ofList [("one", 1), ("two", 2)]
hashMap.contains "one" = true
hashMap.contains "three" = false
```
-/
@[inline] def contains (self : HashMap α β) (a : α) : Bool 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → α → Bool

full_name: Batteries.HashMap.foldM
code: /--
Folds a monadic function over the elements in the map (in arbitrary order).
```
def sumEven (sum: Nat) (k : String) (v : Nat) : Except String Nat :=
  if v % 2 == 0 then pure (sum + v) else throw s!"value {v} at key {k} is not even"

foldM sumEven 0 (ofList [("one", 1), ("three", 3)]) =
  Except.error "value 3 at key three is not even"
foldM sumEven 0 (ofList [("two", 2), ("four", 4)]) = Except.ok 6
```
-/
@[inline] def foldM [Monad m] (f : δ → α → β → m δ) (init : δ) (self : HashMap α β) : m δ 
goal: {x : BEq α} →
  {x_1 : Hashable α} →
    {m : Type u_2 → Type u_3} →
      {δ : Type u_2} → {β : Type u_4} → [inst : Monad m] → (δ → α → β → m δ) → δ → Batteries.HashMap α β → m δ

full_name: Batteries.HashMap.fold
code: /--
Folds a function over the elements in the map (in arbitrary order).
```
fold (fun sum _ v => sum + v) 0 (ofList [("one", 1), ("two", 2)]) = 3
```
-/
@[inline] def fold (f : δ → α → β → δ) (init : δ) (self : HashMap α β) : δ 
goal: {x : BEq α} → {x_1 : Hashable α} → {δ : Type u_2} → {β : Type u_3} → (δ → α → β → δ) → δ → Batteries.HashMap α β → δ

full_name: Batteries.HashMap.mergeWithM
code: /--
Combines two hashmaps using a monadic function `f` to combine two values at a key.
```
def map1 := ofList [("one", 1), ("two", 2)]
def map2 := ofList [("two", 2), ("three", 3)]
def map3 := ofList [("two", 3), ("three", 3)]
def mergeIfNoConflict? (_ : String) (v₁ v₂ : Nat) : Option Nat :=
  if v₁ != v₂ then none else some v₁


mergeWithM mergeIfNoConflict? map1 map2 = some {"one" => 1, "two" => 2, "three" => 3}
mergeWithM mergeIfNoConflict? map1 map3 = none
```
-/
@[specialize] def mergeWithM [Monad m] (f : α → β → β → m β)
    (self other : HashMap α β) : m (HashMap α β) 
goal: {x : BEq α} →
  {x_1 : Hashable α} →
    {m : Type (max u_2 u_1) → Type u_3} →
      {β : Type (max u_2 u_1)} →
        [inst : Monad m] → (α → β → β → m β) → Batteries.HashMap α β → Batteries.HashMap α β → m (Batteries.HashMap α β)

full_name: Batteries.HashMap.mergeWith
code: /--
Combines two hashmaps using function `f` to combine two values at a key.
```
mergeWith (fun _ v₁ v₂ => v₁ + v₂ )
  (ofList [("one", 1), ("two", 2)]) (ofList [("two", 2), ("three", 3)]) =
    {"one" => 1, "two" => 4, "three" => 3}
```
-/
@[inline] def mergeWith (f : α → β → β → β) (self other : HashMap α β) : HashMap α β 
goal: {x : BEq α} →
  {x_1 : Hashable α} →
    {β : Type u_2} → (α → β → β → β) → Batteries.HashMap α β → Batteries.HashMap α β → Batteries.HashMap α β

full_name: Batteries.HashMap.forM
code: /--
Runs a monadic function over the elements in the map (in arbitrary order).
```
def checkEven (k : String) (v : Nat) : Except String Unit :=
  if v % 2 == 0 then pure () else throw s!"value {v} at key {k} is not even"

forM checkEven (ofList [("one", 1), ("three", 3)]) = Except.error "value 3 at key three is not even"
forM checkEven (ofList [("two", 2), ("four", 4)]) = Except.ok ()
```
-/
@[inline] def forM [Monad m] (f : α → β → m PUnit) (self : HashMap α β) : m PUnit 
goal: {x : BEq α} →
  {x_1 : Hashable α} →
    {m : Type u_2 → Type u_3} → {β : Type u_4} → [inst : Monad m] → (α → β → m PUnit) → Batteries.HashMap α β → m PUnit

full_name: Batteries.HashMap.toList
code: /--
Converts the map into a list of key-value pairs.
```
open List
(ofList [("one", 1), ("two", 2)]).toList ~ [("one", 1), ("two", 2)]
```
-/
def toList (self : HashMap α β) : List (α × β) 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → List (α × β)

full_name: Batteries.HashMap.toArray
code: /--
Converts the map into an array of key-value pairs.
```
open List
(ofList [("one", 1), ("two", 2)]).toArray.data ~ #[("one", 1), ("two", 2)].data
```
-/
def toArray (self : HashMap α β) : Array (α × β) 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → Array (α × β)

full_name: Batteries.HashMap.numBuckets
code: /-- The number of buckets in the hash map. -/
def numBuckets (self : HashMap α β) : Nat 
goal: {x : BEq α} → {x_1 : Hashable α} → {β : Type u_2} → Batteries.HashMap α β → Nat

full_name: Batteries.HashMap.ofList
code: /--
Builds a `HashMap` from a list of key-value pairs.
Values of duplicated keys are replaced by their respective last occurrences.
```
ofList [("one", 1), ("one", 2)] = {"one" => 2}
```
-/
def ofList [BEq α] [Hashable α] (l : List (α × β)) : HashMap α β 
goal: Batteries.HashMap α β

full_name: Batteries.HashMap.ofListWith
code: /--
Variant of `ofList` which accepts a function that combines values of duplicated keys.
```
ofListWith [("one", 1), ("one", 2)] (fun v₁ v₂ => v₁ + v₂) = {"one" => 3}
```
-/
def ofListWith [BEq α] [Hashable α] (l : List (α × β)) (f : β → β → β) : HashMap α β 
goal: Batteries.HashMap α β