Zulip Chat Archive
Stream: general
Topic: Why do we use prime numbers in applications of `mixHash`?
l1mey (Sep 30 2025 at 01:47):
Searching for the uses of mixHash I find that chained mixHash calls use prime numbers to distinguish each enum case. Why is that? It this a choice due to the underlying implementation of mixHash ?
-- Lean/Meta/LazyDiscrTree.lean
/-- Hash function -/
protected def hash : Key → UInt64
| .const n a => mixHash 5237 $ mixHash n.hash (hash a)
| .fvar n a => mixHash 3541 $ mixHash (hash n) (hash a)
| .lit v => mixHash 1879 $ hash v
| .star => 7883
| .other => 2411
| .arrow => 17
| .proj s i a => mixHash (hash a) $ mixHash (hash s) (hash i)
-- Lean/Expr.lean
...
with
@[computed_field, extern "lean_expr_data"]
data : @& Expr → Data
| .const n lvls => mkData (mixHash 5 <| mixHash (hash n) (hash lvls)) 0 0 false false (lvls.any Level.hasMVar) (lvls.any Level.hasParam)
| .bvar idx => mkData (mixHash 7 <| hash idx) (idx+1)
| .sort lvl => mkData (mixHash 11 <| hash lvl) 0 0 false false lvl.hasMVar lvl.hasParam
| .fvar fvarId => mkData (mixHash 13 <| hash fvarId) 0 0 true
| .mvar fvarId => mkData (mixHash 17 <| hash fvarId) 0 0 false true
| .mdata _m e =>
Aaron Liu (Sep 30 2025 at 01:56):
maybe because the prime numbers are all coprime to each other
Aaron Liu (Sep 30 2025 at 01:56):
or maybe it's arbitrary
Aaron Liu (Sep 30 2025 at 01:58):
I think I found the mixhash function at https://github.com/leanprover/lean4/blob/7d55c033e1f0ad8cb7c2b9ab72e5db40ce192222/src/runtime/object.cpp#L1714-L1716
Damiano Testa (Sep 30 2025 at 03:10):
This may be completely unrelated, but googling hash and prime numbers yields
https://www.designgurus.io/answers/detail/why-should-hash-functions-use-a-prime-number-modulus
that superficially looks relevant!
Last updated: Dec 20 2025 at 21:32 UTC