bucket_array α β
is the underlying data type for hash_map α β
,
an array of linked lists of key-value pairs.
Equations
- bucket_array α β n = array ↑n (list (Σ (a : α), β a))
Read the bucket corresponding to an element
Equations
- bucket_array.read hash_fn data a = let bidx : fin ↑n := hash_map.mk_idx n (hash_fn a) in array.read data bidx
Write the bucket corresponding to an element
Equations
- bucket_array.write hash_fn data a l = let bidx : fin ↑n := hash_map.mk_idx n (hash_fn a) in array.write data bidx l
Modify (read, apply f
, and write) the bucket corresponding to an element
Equations
- bucket_array.modify hash_fn data a f = let bidx : fin ↑n := hash_map.mk_idx n (hash_fn a) in array.write data bidx (f (array.read data bidx))
The list of all key-value pairs in the bucket list
Equations
- data.as_list = (array.to_list data).join
Fold a function f
over the key-value pairs in the bucket list
Equations
- data.foldl d f = array.foldl data d (λ (b : list (Σ (a : α), β a)) (d : δ), list.foldl (λ (r : δ) (a : Σ (a : α), β a), f r a.fst a.snd) d b)
Insert the pair ⟨a, b⟩
into the correct location in the bucket array
(without checking for duplication)
Equations
- hash_map.reinsert_aux hash_fn data a b = bucket_array.modify hash_fn data a (λ (l : list (Σ (a : α), β a)), ⟨a, b⟩ :: l)
Search a bucket for a key a
and return the value
Equations
- hash_map.find_aux a (⟨a', b⟩ :: t) = dite (a' = a) (λ (h : a' = a), option.some (h.rec_on b)) (λ (h : ¬a' = a), hash_map.find_aux a t)
- hash_map.find_aux a list.nil = option.none
Returns tt
if the bucket l
contains the key a
Equations
- hash_map.contains_aux a l = (hash_map.find_aux a l).is_some
Modify a bucket to replace a value in the list. Leaves the list unchanged if the key is not found.
Equations
- hash_map.replace_aux a b (⟨a', b'⟩ :: t) = ite (a' = a) (⟨a, b⟩ :: t) (⟨a', b'⟩ :: hash_map.replace_aux a b t)
- hash_map.replace_aux a b list.nil = list.nil
Modify a bucket to remove a key, if it exists.
Equations
- hash_map.erase_aux a (⟨a', b'⟩ :: t) = ite (a' = a) t (⟨a', b'⟩ :: hash_map.erase_aux a t)
- hash_map.erase_aux a list.nil = list.nil
- len : bkts.as_list.length = sz
- idx : ∀ {i : fin ↑n} {a : Σ (a : α), β a}, a ∈ array.read bkts i → hash_map.mk_idx n (hash_fn a.fst) = i
- nodup : ∀ (i : fin ↑n), (list.map sigma.fst (array.read bkts i)).nodup
The predicate valid bkts sz
means that bkts
satisfies the hash_map
invariants: There are exactly sz
elements in it, every pair is in the
bucket determined by its key and the hash function, and no key appears
multiple times in the list.
- hash_fn : α → ℕ
- size : ℕ
- nbuckets : ℕ+
- buckets : bucket_array α β c.nbuckets
- is_valid : hash_map.valid c.hash_fn c.buckets c.size
A hash map data structure, representing a finite key-value map
with key type α
and value type β
(which may depend on α
).
Construct an empty hash map with buffer size nbuckets
(default 8).
Return the value corresponding to a key, or none
if not found
Equations
- m.find a = hash_map.find_aux a (bucket_array.read m.hash_fn m.buckets a)
Return tt
if the key exists in the map
Fold a function over the key-value pairs in the map
The list of key-value pairs in the map
The list of keys in the map
Insert a key-value pair into the map. (Modifies m
in-place when applicable)
Equations
- {hash_fn := hash_fn, size := size, nbuckets := n, buckets := buckets, is_valid := v}.insert a b = let bkt : list (Σ (a : α), β a) := bucket_array.read hash_fn buckets a in dite ↥(hash_map.contains_aux a bkt) (λ (hc : ↥(hash_map.contains_aux a bkt)), {hash_fn := hash_fn, size := size, nbuckets := n, buckets := bucket_array.modify hash_fn buckets a (hash_map.replace_aux a b), is_valid := _}) (λ (hc : ¬↥(hash_map.contains_aux a bkt)), let size' : ℕ := size + 1, buckets' : bucket_array α β n := bucket_array.modify hash_fn buckets a (λ (l : list (Σ (a : α), β a)), ⟨a, b⟩ :: l), valid' : hash_map.valid hash_fn (hash_map.reinsert_aux hash_fn buckets a b) (size + 1) := _ in ite (size' ≤ ↑n) {hash_fn := hash_fn, size := size', nbuckets := n, buckets := buckets', is_valid := valid'} (let n' : ℕ+ := ⟨↑n * 2, _⟩, buckets'' : bucket_array α β n' := buckets'.foldl (mk_array ↑n' list.nil) (hash_map.reinsert_aux hash_fn) in {hash_fn := hash_fn, size := size', nbuckets := n', buckets := buckets'', is_valid := _}))
Insert a list of key-value pairs into the map. (Modifies m
in-place when applicable)
Equations
- hash_map.insert_all l m = list.foldl (λ (m : hash_map α β) (_x : Σ (a : α), β a), hash_map.insert_all._match_1 m _x) m l
- hash_map.insert_all._match_1 m ⟨a, b⟩ = m.insert a b
Construct a hash map from a list of key-value pairs.
Equations
- hash_map.of_list l hash_fn = hash_map.insert_all l (mk_hash_map hash_fn (2 * l.length))
Remove a key from the map. (Modifies m
in-place when applicable)
Equations
- m.erase a = hash_map.erase._match_1 m a m
- hash_map.erase._match_1 m a {hash_fn := hash_fn, size := size, nbuckets := n, buckets := buckets, is_valid := v} = dite ↥(hash_map.contains_aux a (bucket_array.read hash_fn buckets a)) (λ (hc : ↥(hash_map.contains_aux a (bucket_array.read hash_fn buckets a))), {hash_fn := hash_fn, size := size - 1, nbuckets := n, buckets := bucket_array.modify hash_fn buckets a (hash_map.erase_aux a), is_valid := _}) (λ (hc : ¬↥(hash_map.contains_aux a (bucket_array.read hash_fn buckets a))), m)
Equations
- hash_map.has_to_string = {to_string := to_string (λ (a : α), _inst_3 a)}