Hash table with separate chaining
Hash Table
StructureHash table with separate chaining#✓fully proved
For a key type \(\alpha\), a value type \(\beta\) and a hash function \(h : \alpha \to \mathbb{N}\), a hash table with hash function \(h\) consists of a positive number \(m\) of buckets and, for each bucket index \(i < m\), a chain stored at bucket \(i\): an association list of key–value pairs whose keys are pairwise distinct. The structure itself does not require keys to lie in their hash-selected bucket.
No expected constant-time bound is claimed because the model supplies neither a probability distribution nor a probabilistic assumption about the hash function.
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
bucketCount : Nat
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:47
Used by 11
DefinitionEmpty hash table#✓fully proved
For a hash function \(h\) and a positive integer \(m\), the empty hash table with hash function \(h\) has \(m\) buckets, each holding the empty chain.
public def empty {α : Type u} {β : Type v} (hash : α → Nat)
(bucketCount : Nat) (bucketCount_pos : 0 < bucketCount) : HashTable α β hash where
bucketCount := bucketCount
bucketCount_pos := bucketCount_pos
buckets := fun _ => ∅
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
Uses 1 · Used by 3
DefinitionHash table lookup#✓fully proved
For a hash table with hash function \(h\) and \(m\) buckets, looking up a key \(k\) searches only the bucket with index \(h(k) \bmod m\): the result is the value bound to \(k\) in that bucket's association list, or nothing if \(k\) has no binding there.
public def lookup {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (table : HashTable α β hash) : Option β :=
AList.lookup key (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩)
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
Uses 1 · Used by 5
DefinitionInsertion into a hash table#✓fully proved
Inserting a key \(k\) with value \(v\) into a hash table with \(m\) buckets and hash function \(h\) keeps the bucket count and every bucket other than bucket \(h(k) \bmod m\), and replaces the chain at bucket \(h(k) \bmod m\) by that chain with \(k\) bound to \(v\): any earlier binding of \(k\) in that chain is removed and the binding of \(k\) to \(v\) is added.
public def insert {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (value : β) (table : HashTable α β hash) : HashTable α β hash where
bucketCount := table.bucketCount
bucketCount_pos := table.bucketCount_pos
buckets := Function.update table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩
(AList.insert key value (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩))
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
Uses 1 · Used by 4
DefinitionValid hash table#✓fully proved
A hash table with hash function \(h\) and \(m\) buckets is valid when every binding lies in its hash-selected bucket: for every bucket index \(i < m\) and every key \(k\), if \(k\) has a binding in bucket \(i\), then \(h(k) \bmod m = i\).
Keys within a single bucket are distinct automatically, since each bucket is an association list.
public def Valid {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Prop :=
∀ (index : Fin table.bucketCount) (key : α),
(AList.lookup key (table.buckets index)).isSome →
(⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩ :
Fin table.bucketCount) = index
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
Uses 1 · Used by 4
DefinitionFinite map represented by a hash table#✓fully proved
The finite map represented by a hash table with \(m\) buckets is built from the list of all bindings of buckets \(0, 1, \dots, m - 1\), concatenated in this order: it binds exactly the keys occurring in this list, and binds each such key to the value of its first binding in the list.
public def abstraction {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Finmap (fun _ : α => β) :=
((List.finRange table.bucketCount).flatMap fun index =>
(table.buckets index).entries).toFinmap
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
Uses 1 · Used by 3
TheoremThe empty hash table is valid#✓fully proved
For every hash function \(h\) and every positive bucket count \(m\), the empty hash table with hash function \(h\) and \(m\) buckets is valid.
public theorem valid_empty {α : Type u} {β : Type v} (hash : α → Nat) [DecidableEq α]
(bucketCount : Nat) (bucketCount_pos : 0 < bucketCount) :
Valid (empty hash bucketCount bucketCount_pos : HashTable α β hash)
public def Valid {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Prop :=
∀ (index : Fin table.bucketCount) (key : α),
(AList.lookup key (table.buckets index)).isSome →
(⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩ :
Fin table.bucketCount) = index
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:83
public def empty {α : Type u} {β : Type v} (hash : α → Nat)
(bucketCount : Nat) (bucketCount_pos : 0 < bucketCount) : HashTable α β hash where
bucketCount := bucketCount
bucketCount_pos := bucketCount_pos
buckets := fun _ => ∅
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:60
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
Uses 3
TheoremLookup in the empty hash table#✓fully proved
For every hash function \(h\), every positive bucket count \(m\) and every key \(k\), looking up \(k\) in the empty hash table with hash function \(h\) and \(m\) buckets finds no value.
@[simp]
public theorem lookup_empty {α : Type u} {β : Type v} (hash : α → Nat) [DecidableEq α]
(bucketCount : Nat) (bucketCount_pos : 0 < bucketCount) (key : α) :
lookup key (empty hash bucketCount bucketCount_pos : HashTable α β hash) = none
public def lookup {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (table : HashTable α β hash) : Option β :=
AList.lookup key (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:67
public def empty {α : Type u} {β : Type v} (hash : α → Nat)
(bucketCount : Nat) (bucketCount_pos : 0 < bucketCount) : HashTable α β hash where
bucketCount := bucketCount
bucketCount_pos := bucketCount_pos
buckets := fun _ => ∅
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:60
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
Uses 2
TheoremThe empty hash table represents the empty map#✓fully proved
For every hash function \(h\) and every positive bucket count \(m\), the finite map represented by the empty hash table with hash function \(h\) and \(m\) buckets is the empty finite map.
@[simp]
public theorem abstraction_empty {α : Type u} {β : Type v} (hash : α → Nat) [DecidableEq α]
(bucketCount : Nat) (bucketCount_pos : 0 < bucketCount) :
abstraction (empty hash bucketCount bucketCount_pos : HashTable α β hash) = ∅
public def abstraction {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Finmap (fun _ : α => β) :=
((List.finRange table.bucketCount).flatMap fun index =>
(table.buckets index).entries).toFinmap
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:91
public def empty {α : Type u} {β : Type v} (hash : α → Nat)
(bucketCount : Nat) (bucketCount_pos : 0 < bucketCount) : HashTable α β hash where
bucketCount := bucketCount
bucketCount_pos := bucketCount_pos
buckets := fun _ => ∅
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:60
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
Uses 2
TheoremHash table lookup after insertion#✓fully proved
For every hash table \(T\), every key \(k\) and every value \(v\), looking up \(k\) in the table obtained by inserting \(k\) with value \(v\) into \(T\) returns \(v\).
public theorem lookup_insert {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (value : β) (table : HashTable α β hash) :
lookup key (insert key value table) = some value
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
public def lookup {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (table : HashTable α β hash) : Option β :=
AList.lookup key (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:67
public def insert {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (value : β) (table : HashTable α β hash) : HashTable α β hash where
bucketCount := table.bucketCount
bucketCount_pos := table.bucketCount_pos
buckets := Function.update table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩
(AList.insert key value (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩))
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:73
Uses 3 · Used by 1
TheoremInsertion does not affect other keys#✓fully proved
For every hash table \(T\), all keys \(k \ne k'\) and every value \(v\), looking up \(k'\) in the table obtained by inserting \(k\) with value \(v\) into \(T\) gives the same result as looking up \(k'\) in \(T\), also when \(k\) and \(k'\) lie in the same bucket.
public theorem lookup_insert_of_ne {α : Type u} {β : Type v} {hash : α → Nat}
[DecidableEq α] (key other : α) (value : β) (table : HashTable α β hash)
(different : other ≠ key) :
lookup other (insert key value table) = lookup other table
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
public def lookup {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (table : HashTable α β hash) : Option β :=
AList.lookup key (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:67
public def insert {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (value : β) (table : HashTable α β hash) : HashTable α β hash where
bucketCount := table.bucketCount
bucketCount_pos := table.bucketCount_pos
buckets := Function.update table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩
(AList.insert key value (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩))
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:73
Uses 3 · Used by 1
TheoremInsertion preserves validity of a hash table#✓fully proved
If a hash table is valid, then the table obtained from it by inserting a key \(k\) with value \(v\) (adding a new binding for \(k\), or replacing the existing one) is again valid.
public theorem valid_insert {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (value : β) (table : HashTable α β hash) (valid : Valid table) :
Valid (insert key value table)
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
public def Valid {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Prop :=
∀ (index : Fin table.bucketCount) (key : α),
(AList.lookup key (table.buckets index)).isSome →
(⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩ :
Fin table.bucketCount) = index
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:83
public def insert {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (value : β) (table : HashTable α β hash) : HashTable α β hash where
bucketCount := table.bucketCount
bucketCount_pos := table.bucketCount_pos
buckets := Function.update table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩
(AList.insert key value (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩))
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:73
Uses 3 · Used by 1
TheoremLookup agrees with the abstraction#✓fully proved
For every valid hash table \(T\) and every key \(k\), looking up \(k\) in the finite map represented by \(T\) gives the same result as looking up \(k\) in \(T\).
public theorem lookup_abstraction {α : Type u} {β : Type v} {hash : α → Nat}
[DecidableEq α] (key : α) (table : HashTable α β hash) (valid : Valid table) :
Finmap.lookup key (abstraction table) = lookup key table
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
public def Valid {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Prop :=
∀ (index : Fin table.bucketCount) (key : α),
(AList.lookup key (table.buckets index)).isSome →
(⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩ :
Fin table.bucketCount) = index
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:83
public def abstraction {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Finmap (fun _ : α => β) :=
((List.finRange table.bucketCount).flatMap fun index =>
(table.buckets index).entries).toFinmap
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:91
public def lookup {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (table : HashTable α β hash) : Option β :=
AList.lookup key (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:67
Uses 4 · Used by 1
TheoremInsertion commutes with the abstraction#✓fully proved
For every valid hash table \(T\), every key \(k\) and every value \(v\), the finite map represented by the table obtained by inserting \(k\) with value \(v\) into \(T\) equals the finite map represented by \(T\) with \(k\) bound to \(v\), replacing any earlier binding of \(k\).
public theorem abstraction_insert {α : Type u} {β : Type v} {hash : α → Nat}
[DecidableEq α] (key : α) (value : β) (table : HashTable α β hash)
(valid : Valid table) :
abstraction (insert key value table) = Finmap.insert key value (abstraction table)
public structure HashTable (α : Type u) (β : Type v) (hash : α → Nat) where
/-- The positive number of chains in the table. -/
bucketCount : Nat
/-- The table has at least one chain. -/
bucketCount_pos : 0 < bucketCount
/-- The canonical association list stored at each bucket. -/
buckets : Fin bucketCount → AList (fun _ : α => β)
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:45
public def Valid {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Prop :=
∀ (index : Fin table.bucketCount) (key : α),
(AList.lookup key (table.buckets index)).isSome →
(⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩ :
Fin table.bucketCount) = index
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:83
public def abstraction {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(table : HashTable α β hash) : Finmap (fun _ : α => β) :=
((List.finRange table.bucketCount).flatMap fun index =>
(table.buckets index).entries).toFinmap
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:91
public def insert {α : Type u} {β : Type v} {hash : α → Nat} [DecidableEq α]
(key : α) (value : β) (table : HashTable α β hash) : HashTable α β hash where
bucketCount := table.bucketCount
bucketCount_pos := table.bucketCount_pos
buckets := Function.update table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩
(AList.insert key value (table.buckets
⟨hash key % table.bucketCount, Nat.mod_lt _ table.bucketCount_pos⟩))
CSLibExt/Algorithms/Lean/DataStructures/HashTable.lean:73
Uses 9
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.