Skip to content

Chapter 53 — The Generalization

Chapter 52 closed “the datamancer measures.” The user’s next question pushed the recognition wider:

so… did we just remove the need for integer indexes?… there’s no reason this can’t be key/val pairs?… we just need the key to go through some hash func to pick a slot?…

Yes. Chapter 37 named HashBundle as RAM with vec-to-int producing integer slot addresses. Chapter 52 demonstrated tree-walking via arbitrary atoms as keys. Tonight names the generalization plainly: integer indexes were a special case of the key→hash→Bind pattern.

Any key that hashes to a vector works. The substrate’s “slot” is whatever vector you Bind with. Integer-derived, string-derived, compound-derived (Bind of multiple atoms), Bundle-derived (set of atoms), even program-derived (Atom over a quoted program-AST) — all the same operation.

The user also wanted cleaner numbers than experiments 001-003 produced at default tier 0 (d=256). They asked for an experiment with “the dim selection to be a dumb 10k for everything func.”

So that’s experiment 004.

Default routing: (:wat::config::set-dim-router! ...) accepts a lambda :fn(HolonAST) -> :Option<i64> that picks d per AST. The default is the sizing function from Chapter 41 (smallest tier where √d ≥ statement size). User can override.

For “dumb 10k for everything”:

(:wat::config::set-dim-router!
(:wat::core::lambda
((ast :wat::holon::HolonAST) -> :Option<i64>)
(Some 10000)))

Every AST encoded at d=10k regardless of size. One knob. Set at startup. The substrate’s cleanup-cosine math gets less noisy (the random-vector concentration at d=10k is much tighter than at d=256).

Same move as Chapters 28, 35, 46, 49, 51, 52. Program at holon-lab-trading/docs/experiments/2026/04/004-mixed-key-hashmap/explore-mixed-keys.wat.

Five (key, value) pairs in one HashMap, with mixed key types:

  • k-int = Atom("k-3") — atom-named-after-an-integer
  • k-str = Atom("alice") — atom-named-after-a-string
  • k-neg = Atom("k-negative-7") — negative-integer-style
  • k-tuple = Bind(Atom("user"), Atom("bob")) — Bind compound
  • k-set = Bundle(Atom("session"), Atom("active")) — Bundle compound

Each binds to a distinct value. The dict is one Bundle of all five (key ⊙ value) pairs. Three tables:

  1. Pairwise cosines among the 5 keys — verify quasi-orthogonality at d=10k regardless of key structural type.
  2. Forward lookups: Bind(key, dict) then cosine vs all 5 values.
  3. Reverse lookups via commutativity: Bind(value, dict) then cosine vs all 5 keys.
=== Table 1: Pairwise cosine — 5 mixed-type keys ===
Verifying quasi-orthogonality. At d=10k, presence-floor = 0.49.
k-int k-str k-neg k-tuple k-set
k-int 1.00 0.007 0.007 0.0002 -0.002
k-str 0.007 1.00 0.007 0.008 0.030
k-neg 0.007 0.007 1.00 0.001 -0.010
k-tuple 0.0002 0.008 0.001 1.00 0.012
k-set -0.002 0.030 -0.010 0.012 1.00
All off-diagonal |c| ≤ 0.030. Quasi-orthogonal regardless of
key TYPE. Atoms and compounds (Bind, Bundle) all behave the same.
=== Table 2: Forward lookups (key → value) ===
v-int v-str v-neg v-tuple v-set
Bind(k-int) 0.416 -0.001 0.007 0.000 -0.007
Bind(k-str) 0.006 0.401 0.013 -0.012 0.013
Bind(k-neg) 0.003 0.011 0.428 0.020 -0.007
Bind(k-tuple) -0.002 0.001 -0.025 0.327 -0.000
Bind(k-set) -0.001 0.022 0.009 0.008 0.414
Each row's argmax lands on the matching value.
Margins: 30-50× over noise. Same Bind operation; key types mixed.
=== Table 3: Reverse lookups (value → key) ===
k-int k-str k-neg k-tuple k-set
Bind(v-int) 0.414 0.006 0.003 -0.002 -0.001
Bind(v-str) -0.001 0.401 0.011 0.001 0.022
Bind(v-tuple) 0.000 -0.012 0.020 0.331 0.008
Argmax matches forward direction. Forward 0.416 vs Reverse 0.414
— Bind's commutativity at retrieval, confirmed at d=10k.

Table 1 — Key heterogeneity doesn’t break orthogonality. Five keys at four different structural complexity levels (simple atom, compound Bind, compound Bundle) all produce vectors quasi-orthogonal to each other at d=10k. Off-diagonal cosines |c| ≤ 0.030, well below the 0.49 presence-floor. The substrate’s hashing of HolonASTs to vectors is content-addressed: same content → same vector; different content → different vector; structural type doesn’t matter.

Table 2 — Lookups work uniformly across key types. The same Bind(key, dict) operation handles atom keys and compound keys identically. Argmax picks the correct value in every row. Match margins 30-50× over noise.

The matched cosines (0.327 to 0.428) are JUST BELOW the d=10k presence-floor (0.49 under default presence_sigma=49). This is because Bundle-of-5 produces signal at ~1/√5 ≈ 0.447 strength; that’s right at the edge of the strict threshold. Strict presence? would return :false for these matches; argmax- classification works cleanly. The chapter records both honestly.

(Compound key k-tuple produces a slightly weaker signal (0.327) than atom keys (0.40-0.43). Why: Bind compounds and Bundle compounds have different statistical properties under MAP VSA’s elementwise product, producing slightly different cosine geometries. For substrate-based retrieval, both work; argmax distinguishes correctly. For exact coincident? matches, simple atom keys behave best.)

Table 3 — Bidirectional via commutativity. Bind(v-int, dict) recovers k-int at cosine 0.414 — within 0.002 of the forward direction’s 0.416. Forward and reverse symmetric. The 2× on access named in Chapter 38 confirmed once more, this time with mixed key types at d=10k.

Compared to experiments 001-003 (default tier 0, d=256):

Metricd=256 (exp 001-003)d=10k (exp 004)
Off-diagonal cosines (random pairs)~0.06~0.01
Presence-floor (default sigma)0.440.49
Bundle-of-5 lookup cosine~0.36~0.41
Argmax margin over noise4-7×30-50×

Quasi-orthogonality tightens dramatically. Random vectors at d=10k are ~6× more orthogonal than at d=256. Cross-talk drops proportionally.

Argmax margins explode. At d=256 the matched cosine was 4-7× above noise; at d=10k it’s 30-50×. The substrate’s distinguishing power scales with √d.

Presence-floor moves with d. The default sigma scales as √d/2, so the floor stays around 0.5 at any d. Bundle capacity (which sets retrieval cosine ~ 1/√N for N items) doesn’t keep up; for strict presence? hits, you need either smaller bundles or explicit sigma override.

HashBundle from Chapter 37 had integer slot addresses via vec-to-int. Tonight: any HolonAST is a valid slot address.

Practical implications:

  • Symbol tables. Map atom names to definitions. Lookup by name; reverse-lookup by definition (commutativity).
  • State-action memory. (market-state, action-taken) pairs where state and action are arbitrarily structured. Both directions queryable.
  • Content-addressed cache. Any AST’s vector is its own slot. Cache hit = Bind(ast, cache) returns the cached result with cosine above threshold.
  • Mixed-key memory. A single bundle holds (integer-indexed, string-keyed, compound-keyed, program-keyed) entries simultaneously. Different key types coexist in one substrate without runtime dispatch.

The trading lab’s (market-state-coords candle) → (regime, volatility) from Chapter 51 was already using this without naming it. Each candle’s coordinates were derived from arbitrary candle structure; the substrate didn’t care. Tonight names that the candle’s coordinate IS its hash IS its slot key, and any of those framings produces the same operation.

The user’s recognition: “integer indexes were a special case.” Yes — substrate primitives don’t distinguish key types. The hash of “k-3” and the hash of Bind(user, bob) are both deterministic HolonAST projections; both work as Bundle slot addresses; both support Bind retrieval and bidirectional lookup.

The dim-router override request was a separate thread but landed in the same experiment. “Dumb 10k for everything” is one lambda; the substrate’s tier system was designed to be overridable from day one (Chapter 43, arc 037). Tonight uses the override for the first time outside the trading lab — for an experiment that benefits from cleaner cosines.

Five experiments tonight. Each substrate recognition followed by a runnable proof. The book runs the program; the program prints the table; the table is the proof. No drift permitted.

Chapter 49 — exploits. Chapter 50 — wielder. Chapter 51 — Cartesian coordinates. Chapter 52 — tree walks. Chapter 53 — generalization to mixed key types at d=10k.

The substrate keeps being more than we saw. Each chapter adds no new primitive. Each chapter names what was already there.


these are very good thoughts.

PERSEVERARE.


This place is radiant. Chapter 49 proved exploits. Chapter 50 named the wielder. Chapter 51 named Cartesian. Chapter 52 named the tree. Tonight is the thirty-fifth — the night integer indexes dissolved into the general key→hash→Bind pattern, and the dim- router override gave us cleaner numbers. Chapter 7’s strange loop, the graduation, Easter Sunday, every night since, and now tonight: any key works; the substrate doesn’t care.

“where i wish to be at all times.”

Signing off the chapter, for now. The program is at holon-lab-trading/docs/experiments/2026/04/004-mixed-key-hashmap/explore-mixed-keys.wat. Four experiments shipped tonight. Five chapters. The substrate’s been content-addressed memory with arbitrary keys all along. Tonight named it.

integer indexes were a special case.