Skip to content

feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy)#2650

Draft
jucor wants to merge 1 commit into
spr/edge/0add28f3from
spr/edge/d5f1f51d
Draft

feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy)#2650
jucor wants to merge 1 commit into
spr/edge/0add28f3from
spr/edge/d5f1f51d

Conversation

@jucor

@jucor jucor commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

The greedy floor (conversation.clj:259-268) sorts the user-vote-counts
hash-map with a STABLE sort by count desc — so equal-count ties follow
Clojure's PersistentHashMap ITERATION ORDER, which is deterministic:
sort by successive 5-bit chunks (low first) of Murmur3 hashLong
(Clojure hasheq for Long keys). Validated against three recorded-blob
oracles (user-vote-counts raw key order: vw front-loaded6 n=18, vw
uniform8 n=30, biodiversity n=98 — all exact).

The PR-E port assumed this order was non-deterministic and substituted
matrix row order; on vw front-loaded6 step 0 that admits pid 14 where
Clojure admits pid 17 (five-way 1-vote tie at the floor boundary),
seeding an in-conv/base-cluster membership divergence that cascades
through every downstream key — the battery's last diverging entry.

Adds polismath/utils/clj_hash.py (hashLong + HAMT key order; int keys
only, with a documented row-order fallback otherwise) and applies it to
the legacy greedy candidate order. Array-map (≤8 entries, insertion
order) cannot affect the pick: ties only matter with ≥16 participants,
which guarantees hash-map. Improved mode unchanged.

commit-id:d5f1f51d


Stack:


⚠️ Part of a stack created by spr. Do not merge manually using the UI - doing so may have unexpected results.

This was referenced Jul 22, 2026
@jucor
jucor force-pushed the spr/edge/0add28f3 branch from f5a2c36 to aa5a214 Compare July 22, 2026 02:31
@jucor
jucor force-pushed the spr/edge/d5f1f51d branch from 16a2920 to 1f33fd2 Compare July 22, 2026 02:31
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) feat(math): Clojure hash-map iteration order for the in-conv greedy t… Jul 22, 2026
@jucor
jucor changed the base branch from spr/edge/0add28f3 to edge July 22, 2026 03:54
@jucor
jucor force-pushed the spr/edge/d5f1f51d branch from 1f33fd2 to 288f984 Compare July 22, 2026 03:54
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy t… feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) Jul 22, 2026
@jucor
jucor changed the base branch from edge to spr/edge/0add28f3 July 22, 2026 03:54
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) feat(math): Clojure hash-map iteration order for the in-conv greedy t… Jul 22, 2026
@jucor
jucor changed the base branch from spr/edge/0add28f3 to edge July 22, 2026 06:50
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy t… feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) Jul 22, 2026
@jucor
jucor changed the base branch from edge to spr/edge/0add28f3 July 22, 2026 06:50
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) feat(math): Clojure hash-map iteration order for the in-conv greedy t… Jul 22, 2026
@jucor
jucor changed the base branch from spr/edge/0add28f3 to edge July 22, 2026 08:11
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy t… feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) Jul 22, 2026
@jucor
jucor changed the base branch from edge to spr/edge/0add28f3 July 22, 2026 08:11
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) feat(math): Clojure hash-map iteration order for the in-conv greedy t… Jul 22, 2026
@jucor
jucor changed the base branch from spr/edge/0add28f3 to edge July 22, 2026 09:58
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy t… feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) Jul 22, 2026
@jucor
jucor changed the base branch from edge to spr/edge/0add28f3 July 22, 2026 09:58
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) feat(math): Clojure hash-map iteration order for the in-conv greedy t… Jul 22, 2026
@jucor
jucor changed the base branch from spr/edge/0add28f3 to edge July 22, 2026 11:20
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy t… feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) Jul 22, 2026
@jucor
jucor changed the base branch from edge to spr/edge/0add28f3 July 22, 2026 11:21
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) feat(math): Clojure hash-map iteration order for the in-conv greedy t… Jul 24, 2026
@jucor
jucor changed the base branch from spr/edge/0add28f3 to edge July 24, 2026 06:02
@jucor jucor changed the title feat(math): Clojure hash-map iteration order for the in-conv greedy t… feat(math): Clojure hash-map iteration order for the in-conv greedy tie-break (legacy) Jul 24, 2026
@jucor
jucor changed the base branch from edge to spr/edge/0add28f3 July 24, 2026 06:02
@jucor
jucor requested a review from Copilot July 25, 2026 22:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restores Clojure-legacy parity for the in-conversation (“in-conv”) greedy-floor tie-break by reproducing Clojure PersistentHashMap iteration order (Murmur3 hashLong + HAMT 5-bit chunk traversal) for integer (and numeric-string) keys, and using that ordering as the stable-sort tie base.

Changes:

  • Add polismath.utils.clj_hash implementing Clojure hashLong and HAMT-based key iteration order for int-like keys (with a documented fallback).
  • Update legacy-mode greedy-floor candidate ordering in Conversation._get_in_conv_participants to follow Clojure hash-map iteration order on equal vote-count ties.
  • Add targeted unit/integration tests that pin known hash/HAMT order and validate the greedy-floor tie outcome for both int and string pid shapes.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
delphi/tests/test_clj_hash_order.py Adds regression tests for Clojure hash-map key order and legacy greedy-floor tie behavior (int + string pids).
delphi/polismath/utils/clj_hash.py Implements Murmur3 hashLong and a HAMT-path-based ordering function to emulate Clojure PersistentHashMap iteration order.
delphi/polismath/conversation/conversation.py Switches legacy greedy-floor tie-breaking to Clojure hash-map order by pre-ordering candidates before stable vote-count sorting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


from __future__ import annotations

import pytest
Comment on lines +18 to +21
Caveats, deliberate and documented:
- Integer keys only. Other key types hash differently (e.g. String hasheq is
Murmur3 over ``String.hashCode``); :func:`clojure_hash_map_key_order` falls
back to the given order for them rather than guessing.
Comment on lines +2067 to +2071
candidates = [
pid for pid in clojure_hash_map_key_order(vote_counts.keys())
if pid not in in_conv
]
candidates.sort(key=lambda pid: -vote_counts[pid]) # stable -> clj-map ties
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants