@hviana/sema 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/example/demo.d.ts +1 -0
  2. package/dist/example/demo.js +39 -0
  3. package/dist/example/train_base.d.ts +87 -0
  4. package/dist/example/train_base.js +2252 -0
  5. package/dist/src/alphabet.d.ts +7 -0
  6. package/dist/src/alphabet.js +33 -0
  7. package/dist/src/alu/src/alu.d.ts +185 -0
  8. package/dist/src/alu/src/alu.js +440 -0
  9. package/dist/src/alu/src/expr.d.ts +61 -0
  10. package/dist/src/alu/src/expr.js +318 -0
  11. package/dist/src/alu/src/index.d.ts +11 -0
  12. package/dist/src/alu/src/index.js +19 -0
  13. package/dist/src/alu/src/kernel-arith.d.ts +16 -0
  14. package/dist/src/alu/src/kernel-arith.js +264 -0
  15. package/dist/src/alu/src/kernel-bits.d.ts +19 -0
  16. package/dist/src/alu/src/kernel-bits.js +152 -0
  17. package/dist/src/alu/src/kernel-logic.d.ts +4 -0
  18. package/dist/src/alu/src/kernel-logic.js +60 -0
  19. package/dist/src/alu/src/kernel-nd.d.ts +3 -0
  20. package/dist/src/alu/src/kernel-nd.js +208 -0
  21. package/dist/src/alu/src/kernel-numeric.d.ts +54 -0
  22. package/dist/src/alu/src/kernel-numeric.js +366 -0
  23. package/dist/src/alu/src/operation.d.ts +168 -0
  24. package/dist/src/alu/src/operation.js +189 -0
  25. package/dist/src/alu/src/parser.d.ts +221 -0
  26. package/dist/src/alu/src/parser.js +577 -0
  27. package/dist/src/alu/src/resonance.d.ts +55 -0
  28. package/dist/src/alu/src/resonance.js +126 -0
  29. package/dist/src/alu/src/text.d.ts +31 -0
  30. package/dist/src/alu/src/text.js +73 -0
  31. package/dist/src/alu/src/value.d.ts +109 -0
  32. package/dist/src/alu/src/value.js +300 -0
  33. package/dist/src/alu/test/alu.test.d.ts +1 -0
  34. package/dist/src/alu/test/alu.test.js +764 -0
  35. package/dist/src/bytes.d.ts +14 -0
  36. package/dist/src/bytes.js +59 -0
  37. package/dist/src/canon.d.ts +26 -0
  38. package/dist/src/canon.js +57 -0
  39. package/dist/src/config.d.ts +111 -0
  40. package/dist/src/config.js +91 -0
  41. package/dist/src/derive/src/deduction.d.ts +136 -0
  42. package/dist/src/derive/src/deduction.js +159 -0
  43. package/dist/src/derive/src/index.d.ts +8 -0
  44. package/dist/src/derive/src/index.js +11 -0
  45. package/dist/src/derive/src/priority-queue.d.ts +20 -0
  46. package/dist/src/derive/src/priority-queue.js +73 -0
  47. package/dist/src/derive/src/rewrite.d.ts +56 -0
  48. package/dist/src/derive/src/rewrite.js +100 -0
  49. package/dist/src/derive/src/trie.d.ts +90 -0
  50. package/dist/src/derive/src/trie.js +217 -0
  51. package/dist/src/derive/test/derive.test.d.ts +1 -0
  52. package/dist/src/derive/test/derive.test.js +122 -0
  53. package/dist/src/extension.d.ts +37 -0
  54. package/dist/src/extension.js +7 -0
  55. package/dist/src/geometry.d.ts +175 -0
  56. package/dist/src/geometry.js +823 -0
  57. package/dist/src/index.d.ts +17 -0
  58. package/dist/src/index.js +19 -0
  59. package/dist/src/ingest-cache.d.ts +41 -0
  60. package/dist/src/ingest-cache.js +165 -0
  61. package/dist/src/meter.d.ts +176 -0
  62. package/dist/src/meter.js +274 -0
  63. package/dist/src/mind/articulation.d.ts +6 -0
  64. package/dist/src/mind/articulation.js +99 -0
  65. package/dist/src/mind/attention.d.ts +414 -0
  66. package/dist/src/mind/attention.js +2082 -0
  67. package/dist/src/mind/bridge.d.ts +39 -0
  68. package/dist/src/mind/bridge.js +972 -0
  69. package/dist/src/mind/canonical.d.ts +34 -0
  70. package/dist/src/mind/canonical.js +93 -0
  71. package/dist/src/mind/graph-search.d.ts +294 -0
  72. package/dist/src/mind/graph-search.js +996 -0
  73. package/dist/src/mind/index.d.ts +9 -0
  74. package/dist/src/mind/index.js +5 -0
  75. package/dist/src/mind/junction.d.ts +137 -0
  76. package/dist/src/mind/junction.js +342 -0
  77. package/dist/src/mind/learning.d.ts +75 -0
  78. package/dist/src/mind/learning.js +270 -0
  79. package/dist/src/mind/match.d.ts +181 -0
  80. package/dist/src/mind/match.js +655 -0
  81. package/dist/src/mind/mechanisms/alu.d.ts +4 -0
  82. package/dist/src/mind/mechanisms/alu.js +36 -0
  83. package/dist/src/mind/mechanisms/cast.d.ts +89 -0
  84. package/dist/src/mind/mechanisms/cast.js +784 -0
  85. package/dist/src/mind/mechanisms/confluence.d.ts +24 -0
  86. package/dist/src/mind/mechanisms/confluence.js +255 -0
  87. package/dist/src/mind/mechanisms/cover.d.ts +6 -0
  88. package/dist/src/mind/mechanisms/cover.js +227 -0
  89. package/dist/src/mind/mechanisms/extraction.d.ts +33 -0
  90. package/dist/src/mind/mechanisms/extraction.js +300 -0
  91. package/dist/src/mind/mechanisms/recall.d.ts +16 -0
  92. package/dist/src/mind/mechanisms/recall.js +364 -0
  93. package/dist/src/mind/mind.d.ts +337 -0
  94. package/dist/src/mind/mind.js +626 -0
  95. package/dist/src/mind/pipeline-mechanism.d.ts +172 -0
  96. package/dist/src/mind/pipeline-mechanism.js +465 -0
  97. package/dist/src/mind/pipeline.d.ts +49 -0
  98. package/dist/src/mind/pipeline.js +275 -0
  99. package/dist/src/mind/primitives.d.ts +66 -0
  100. package/dist/src/mind/primitives.js +306 -0
  101. package/dist/src/mind/rationale.d.ts +139 -0
  102. package/dist/src/mind/rationale.js +163 -0
  103. package/dist/src/mind/reasoning.d.ts +40 -0
  104. package/dist/src/mind/reasoning.js +280 -0
  105. package/dist/src/mind/recognition.d.ts +20 -0
  106. package/dist/src/mind/recognition.js +504 -0
  107. package/dist/src/mind/resonance.d.ts +23 -0
  108. package/dist/src/mind/resonance.js +0 -0
  109. package/dist/src/mind/trace.d.ts +15 -0
  110. package/dist/src/mind/trace.js +73 -0
  111. package/dist/src/mind/traverse.d.ts +126 -0
  112. package/dist/src/mind/traverse.js +650 -0
  113. package/dist/src/mind/types.d.ts +333 -0
  114. package/dist/src/mind/types.js +130 -0
  115. package/dist/src/rabitq-ivf/src/database.d.ts +113 -0
  116. package/dist/src/rabitq-ivf/src/database.js +201 -0
  117. package/dist/src/rabitq-ivf/src/index.d.ts +7 -0
  118. package/dist/src/rabitq-ivf/src/index.js +4 -0
  119. package/dist/src/rabitq-ivf/src/ivf.d.ts +200 -0
  120. package/dist/src/rabitq-ivf/src/ivf.js +1165 -0
  121. package/dist/src/rabitq-ivf/src/prng.d.ts +19 -0
  122. package/dist/src/rabitq-ivf/src/prng.js +36 -0
  123. package/dist/src/rabitq-ivf/src/rabitq.d.ts +95 -0
  124. package/dist/src/rabitq-ivf/src/rabitq.js +283 -0
  125. package/dist/src/sema.d.ts +31 -0
  126. package/dist/src/sema.js +63 -0
  127. package/dist/src/store-sqlite.d.ts +184 -0
  128. package/dist/src/store-sqlite.js +942 -0
  129. package/dist/src/store.d.ts +678 -0
  130. package/dist/src/store.js +1703 -0
  131. package/dist/src/vec.d.ts +31 -0
  132. package/dist/src/vec.js +109 -0
  133. package/package.json +1 -1
  134. package/src/mind/bridge.ts +55 -18
  135. package/src/mind/mind.ts +11 -2
@@ -0,0 +1,31 @@
1
+ export type Vec = Float32Array;
2
+ /** Deterministic PRNG (32-bit mixer). */
3
+ export declare function rng(seed: number): () => number;
4
+ export declare const zeros: (D: number) => Vec;
5
+ export declare const copy: (v: Vec) => Vec;
6
+ /** Random point on the unit sphere. */
7
+ export declare function randomUnit(D: number, rand: () => number): Vec;
8
+ /** target += src * scale (in place). */
9
+ export declare function addInto(target: Vec, src: Vec, scale?: number): Vec;
10
+ export declare function dot(a: Vec, b: Vec): number;
11
+ /** In-place normalization. */
12
+ export declare function normalize(v: Vec): Vec;
13
+ /** Resonance: 1 = same, 0 = unrelated. */
14
+ export declare function cosine(a: Vec, b: Vec): number;
15
+ /** Set vector epsilon thresholds. Called once by Mind at construction. */
16
+ export declare function setVecConfig(cfg: {
17
+ normalizeEpsilon?: number;
18
+ cosineEpsilon?: number;
19
+ }): void;
20
+ export interface Permutation {
21
+ fwd: Uint32Array;
22
+ inv: Uint32Array;
23
+ }
24
+ /** The keyring: one independent permutation per seat.
25
+ * Independent keys do not commute, so an address in a tree is the
26
+ * path itself — "seat 2 inside seat 1" ≠ "seat 1 inside seat 2". */
27
+ export declare function makeKeyring(D: number, seats: number, rand: () => number): Permutation[];
28
+ /** Apply permutation: out[i] = v[table[i]]. */
29
+ export declare function permute(v: Vec, table: Uint32Array): Vec;
30
+ /** Permute into existing buffer — zero allocation. */
31
+ export declare function permuteInto(out: Vec, v: Vec, table: Uint32Array): Vec;
@@ -0,0 +1,109 @@
1
+ // vec.ts — vector primitives.
2
+ // Superposition (add), normalization (stay on the sphere),
3
+ // resonance (cosine), and seat binding (a keyring of fixed permutations).
4
+ // No weights. No gradients.
5
+ /** Deterministic PRNG (32-bit mixer). */
6
+ export function rng(seed) {
7
+ let s = seed >>> 0;
8
+ return () => {
9
+ s = (s + 0x6d2b79f5) >>> 0;
10
+ let t = s;
11
+ t = Math.imul(t ^ (t >>> 15), t | 1);
12
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
13
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
14
+ };
15
+ }
16
+ /** Standard normal sample (Box–Muller). */
17
+ function gaussian(rand) {
18
+ let u = 0, v = 0;
19
+ while (u === 0)
20
+ u = rand();
21
+ while (v === 0)
22
+ v = rand();
23
+ return Math.sqrt(-2 * Math.log(u)) * Math.cos(2 * Math.PI * v);
24
+ }
25
+ export const zeros = (D) => new Float32Array(D);
26
+ export const copy = (v) => new Float32Array(v);
27
+ /** Random point on the unit sphere. */
28
+ export function randomUnit(D, rand) {
29
+ const v = zeros(D);
30
+ for (let i = 0; i < D; i++)
31
+ v[i] = gaussian(rand);
32
+ return normalize(v);
33
+ }
34
+ /** target += src * scale (in place). */
35
+ export function addInto(target, src, scale = 1) {
36
+ for (let i = 0; i < target.length; i++)
37
+ target[i] += src[i] * scale;
38
+ return target;
39
+ }
40
+ export function dot(a, b) {
41
+ let s = 0;
42
+ for (let i = 0; i < a.length; i++)
43
+ s += a[i] * b[i];
44
+ return s;
45
+ }
46
+ const norm = (v) => Math.sqrt(dot(v, v));
47
+ // Epsilon thresholds (settable once via setVecConfig).
48
+ let _normalizeEpsilon = 1e-12;
49
+ let _cosineEpsilon = 1e-12;
50
+ /** In-place normalization. */
51
+ export function normalize(v) {
52
+ const n = norm(v);
53
+ if (n > _normalizeEpsilon) {
54
+ for (let i = 0; i < v.length; i++)
55
+ v[i] /= n;
56
+ }
57
+ return v;
58
+ }
59
+ /** Resonance: 1 = same, 0 = unrelated. */
60
+ export function cosine(a, b) {
61
+ const na = norm(a), nb = norm(b);
62
+ return na > _cosineEpsilon && nb > _cosineEpsilon ? dot(a, b) / (na * nb) : 0;
63
+ }
64
+ /** Set vector epsilon thresholds. Called once by Mind at construction. */
65
+ export function setVecConfig(cfg) {
66
+ if (cfg.normalizeEpsilon !== undefined) {
67
+ _normalizeEpsilon = cfg.normalizeEpsilon;
68
+ }
69
+ if (cfg.cosineEpsilon !== undefined)
70
+ _cosineEpsilon = cfg.cosineEpsilon;
71
+ }
72
+ /** One fixed random permutation (Fisher–Yates). */
73
+ function makePermutation(D, rand) {
74
+ const fwd = new Uint32Array(D);
75
+ for (let i = 0; i < D; i++)
76
+ fwd[i] = i;
77
+ for (let i = D - 1; i > 0; i--) {
78
+ const j = Math.floor(rand() * (i + 1));
79
+ const t = fwd[i];
80
+ fwd[i] = fwd[j];
81
+ fwd[j] = t;
82
+ }
83
+ const inv = new Uint32Array(D);
84
+ for (let i = 0; i < D; i++)
85
+ inv[fwd[i]] = i;
86
+ return { fwd, inv };
87
+ }
88
+ /** The keyring: one independent permutation per seat.
89
+ * Independent keys do not commute, so an address in a tree is the
90
+ * path itself — "seat 2 inside seat 1" ≠ "seat 1 inside seat 2". */
91
+ export function makeKeyring(D, seats, rand) {
92
+ const ring = [];
93
+ for (let s = 0; s < seats; s++)
94
+ ring.push(makePermutation(D, rand));
95
+ return ring;
96
+ }
97
+ /** Apply permutation: out[i] = v[table[i]]. */
98
+ export function permute(v, table) {
99
+ const out = new Float32Array(v.length);
100
+ for (let i = 0; i < v.length; i++)
101
+ out[i] = v[table[i]];
102
+ return out;
103
+ }
104
+ /** Permute into existing buffer — zero allocation. */
105
+ export function permuteInto(out, v, table) {
106
+ for (let i = 0; i < v.length; i++)
107
+ out[i] = v[table[i]];
108
+ return out;
109
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hviana/sema",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Sema: a non-parametric, instance-based reasoning system.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -594,27 +594,62 @@ async function bridgeImpl(
594
594
  // hundreds of roots), so this is where its proposals are first sized.
595
595
  //
596
596
  // Candidate bytes are read LAZILY — on first access during the seed
597
- // check — not eagerly for every collected id. On a 325K-context store
598
- // the climb channel alone can propose hundreds of edge-bearing ancestors
599
- // (hubBound = 571), most of which will never contain a picked anchor
600
- // window and would be discarded at the seed check without their bytes
601
- // ever being consulted. Eager reads for 500+ candidates each traversing
602
- // the DAG (profiled at 12K node records and 73KB of bytes read per
603
- // refusing query) is the dominant remaining bridge cost after the ANN
604
- // gate. A Map stays available for the frame-unanimity scan below, which
605
- // only needs bytes of candidates that actually seeded.
606
- const seededBytes = new Map<number, Uint8Array>();
607
- /** Read a candidate's bytes once; cache for the seed check AND for the
608
- * frame-unanimity scan that follows alignment. Returns null when the
609
- * candidate exceeds the phrase-scale cap or has no content. */
597
+ // check — not eagerly for every collected id. Most climb-proposed
598
+ // candidates fail the seed check and never reach the expensive identity
599
+ // and frame-consensus gates.
600
+ //
601
+ // Frame unanimity is different: once any candidate reaches that gate, it
602
+ // must be evaluated against the COMPLETE collected candidate population,
603
+ // not only the prefix whose bytes happened to be loaded earlier. The full
604
+ // phrase-scale population is therefore materialised once, lazily, on the
605
+ // first unanimous() call and reused afterward.
606
+ //
607
+ // Null results are memoised too, so an empty or over-cap candidate is never
608
+ // read repeatedly by the candidate loop and the population materialiser.
609
+ const candidateByteMemo = new Map<number, Uint8Array | null>();
610
+
611
+ /** Read one candidate at most once. Returns null when it exceeds the
612
+ * phrase-scale cap or has no content. */
610
613
  const bytesOfCandidate = (sid: number): Uint8Array | null => {
611
- const hit = seededBytes.get(sid);
612
- if (hit !== undefined) return hit;
614
+ const cached = candidateByteMemo.get(sid);
615
+ if (cached !== undefined) return cached;
616
+
613
617
  const b = candidateBytes(sid);
614
- if (b !== null) seededBytes.set(sid, b);
618
+ candidateByteMemo.set(sid, b);
615
619
  return b;
616
620
  };
617
- if (diagnostics) diagnostics.phraseScale = seededBytes.size;
621
+
622
+ let framePopulation: Map<number, Uint8Array> | null = null;
623
+
624
+ /** Return the complete phrase-scale candidate population.
625
+ *
626
+ * This is intentionally lazy: queries that never reach frame unanimity
627
+ * keep the cheap per-candidate seed path. Once required, every candidate
628
+ * is bounded by candidateBytes(), loaded at most once, and all subsequent
629
+ * unanimity checks observe the same order-independent population.
630
+ */
631
+ const ensureFramePopulation = (): ReadonlyMap<number, Uint8Array> => {
632
+ if (framePopulation !== null) {
633
+ return framePopulation;
634
+ }
635
+
636
+ const complete = new Map<number, Uint8Array>();
637
+
638
+ for (const sid of candidates) {
639
+ const bytes = bytesOfCandidate(sid);
640
+ if (bytes !== null) {
641
+ complete.set(sid, bytes);
642
+ }
643
+ }
644
+
645
+ framePopulation = complete;
646
+
647
+ if (diagnostics) {
648
+ diagnostics.phraseScale = complete.size;
649
+ }
650
+
651
+ return complete;
652
+ };
618
653
 
619
654
  // FRAME UNANIMITY: a substitution U → C inside the frame (Lf, Rf) is
620
655
  // groundable only when the collected candidates — the store's own sample
@@ -639,7 +674,9 @@ async function bridgeImpl(
639
674
  lf: Uint8Array,
640
675
  rf: Uint8Array,
641
676
  ): boolean => {
642
- for (const bytes of seededBytes.values()) {
677
+ const population = ensureFramePopulation();
678
+
679
+ for (const bytes of population.values()) {
643
680
  let from = 0;
644
681
  for (;;) {
645
682
  const i = indexOf(bytes, lf, from);
package/src/mind/mind.ts CHANGED
@@ -482,8 +482,17 @@ export class Mind implements MindContext {
482
482
  // Inference is a pure function of cumulative bytes. Conversation
483
483
  // boundaries remain persistence/API metadata and must not select a
484
484
  // different mechanism path than respond() on the identical byte stream.
485
- this.answeredSpans = [];
486
- this.currentTurnStart = 0;
485
+ // answeredSpans and currentTurnStart ARE restored from the conversation,
486
+ // however — they are pure functions of the cumulative byte stream (the
487
+ // assistant's own prior replies, and where the current user turn starts,
488
+ // are deterministic given the full transcript). Without them confluence,
489
+ // cover, the weave, and the consensus climb treat prior assistant turns
490
+ // as fresh query content — re-deriving them as constraints, voting
491
+ // anchors, and alignment points.
492
+ this.answeredSpans = conv ? conv.answeredSpans : [];
493
+ this.currentTurnStart = conv && conv.boundaries.length > 0
494
+ ? conv.boundaries[conv.boundaries.length - 1]
495
+ : 0;
487
496
  this.canon = canon ?? null;
488
497
  this.canonMemo = canon ? new Map() : null;
489
498
  this._beginMeter();