import unittest from hdc.hypervec import hvc, sim from hdc.memory_modes import ( HolographicMemory, HybridMemory, PhotographicMemory, capacity_report, compare_modes, ) D = 2000 SYMBOLS = [hvc("test/symbol/%d" % i, D) for i in range(8)] class TestPhotographic(unittest.TestCase): def test_recall_is_bit_exact(self): mem = PhotographicMemory(d=D) value = hvc("pixel/42", D) mem.capture("frame/42", value) got, score = mem.recall("frame/42") self.assertEqual(got, value & ((1 << D) - 1)) self.assertEqual(score, 1.0) def test_miss_is_none(self): mem = PhotographicMemory(d=D) self.assertEqual(mem.recall("absent"), (None, 0.0)) def test_capacity_evicts_oldest(self): mem = PhotographicMemory(d=D, capacity=2) for i in range(3): mem.capture("k/%d" % i, SYMBOLS[i]) self.assertEqual(len(mem), 2) self.assertNotIn("k/0", mem) self.assertIn("k/2", mem) self.assertEqual(mem.stats()["evicted"], 1) def test_overwrite_does_not_evict(self): mem = PhotographicMemory(d=D, capacity=1) mem.capture("k", SYMBOLS[0]) mem.capture("k", SYMBOLS[1]) self.assertEqual(mem.recall("k")[0], SYMBOLS[1]) self.assertEqual(mem.stats()["evicted"], 0) class TestHolographic(unittest.TestCase): def test_majority_superposition_recalls_exactly_at_small_k(self): mem = HolographicMemory(d=D, alphabet=SYMBOLS) for i in range(4): mem.record("slot/%d" % i, SYMBOLS[i]) for i in range(4): got, _ = mem.recall("slot/%d" % i) self.assertEqual(got, SYMBOLS[i], msg="slot %d" % i) def test_xor_accumulation_is_the_wrong_rule(self): # Regression: XOR crosstalk is itself random at every bit, so unbinding # is chance at any k. Majority is what makes recall work at all. # Measured: XOR recalls 0/2, 0/4, 2/8 (chance); majority 8/8. from hdc.hypervec import bind for k in (2, 4, 8): trace = 0 for i in range(k): trace ^= bind(hvc("xor/%d" % i, D), SYMBOLS[i], D) xor_hits = 0 for i in range(k): probe = bind(trace, hvc("xor/%d" % i, D), D) best = max(SYMBOLS, key=lambda s: sim(probe, s, D)) xor_hits += best == SYMBOLS[i] self.assertLessEqual(xor_hits, k // 2, msg="k=%d" % k) majority = HolographicMemory(d=D, alphabet=SYMBOLS) for i in range(k): majority.record("xor/%d" % i, SYMBOLS[i]) self.assertEqual( sum(1 for i in range(k) if majority.recall("xor/%d" % i)[0] == SYMBOLS[i]), k, msg="k=%d" % k, ) def test_confidence_falls_as_the_trace_fills(self): mem = HolographicMemory(d=D, alphabet=SYMBOLS) mem.record("slot/0", SYMBOLS[0]) alone = mem.confidence("slot/0") for i in range(1, 6): mem.record("slot/%d" % i, SYMBOLS[i]) crowded = mem.confidence("slot/0") self.assertLess(crowded, alone) self.assertGreater(alone, 0.9) def test_empty_memory_returns_nothing(self): mem = HolographicMemory(d=D, alphabet=SYMBOLS) self.assertEqual(mem.recall("anything"), (None, 0.0)) self.assertEqual(mem.confidence("anything"), 0.0) def test_trace_is_bounded_by_dimension(self): mem = HolographicMemory(d=D, alphabet=SYMBOLS) for i in range(8): mem.record("slot/%d" % i, SYMBOLS[i]) self.assertLess(mem.trace.bit_length(), D + 1) self.assertEqual(mem.stats()["items"], 8) def test_capacity_report_is_monotone_in_similarity(self): rows = capacity_report(D, sizes=(2, 8, 16), symbols=8) self.assertEqual([r["items"] for r in rows], [2, 8, 16]) for earlier, later in zip(rows, rows[1:]): self.assertLessEqual(later["mean_similarity"], earlier["mean_similarity"]) class TestHybrid(unittest.TestCase): def test_exact_path_wins_when_present(self): mem = HybridMemory(d=D, buckets=4, alphabet=SYMBOLS) mem.capture("key/1", SYMBOLS[1]) value, score, path = mem.recall("key/1") self.assertEqual((value, score, path), (SYMBOLS[1], 1.0, "exact")) def test_trace_path_answers_after_eviction(self): mem = HybridMemory(d=D, buckets=1, per_bucket=1, alphabet=SYMBOLS) mem.capture("first", SYMBOLS[0]) mem.capture("second", SYMBOLS[1]) # evicts "first" from the exact index self.assertNotIn("first", mem.exact[0]) value, score, path = mem.recall("first") self.assertEqual(path, "trace") self.assertIsNotNone(value) def test_buckets_are_disjoint(self): mem = HybridMemory(d=D, buckets=8, alphabet=SYMBOLS) mem.capture("key/1", SYMBOLS[1]) filled = [i for i, cell in enumerate(mem.exact) if cell] self.assertEqual(len(filled), 1) def test_consolidate_matches_a_fresh_trace(self): mem = HybridMemory(d=D, buckets=2, alphabet=SYMBOLS) for i in range(4): mem.capture("k/%d" % i, SYMBOLS[i]) self.assertEqual(mem.consolidate(), 0) for i in range(4): self.assertEqual(mem.recall("k/%d" % i)[0], SYMBOLS[i]) def test_compare_modes_photographic_is_perfect(self): result = compare_modes(D, k=8, symbols=8) self.assertEqual(result["photographic"], 1.0) self.assertEqual(result["items"], 8) def test_zero_buckets_rejected(self): with self.assertRaises(ValueError): HybridMemory(d=D, buckets=0) if __name__ == "__main__": unittest.main()