@hviana/sema 0.1.5 → 0.1.7
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.
- package/AGENTS.md +6 -5
- package/CITATION.cff +49 -0
- package/HOW_IT_WORKS.md +11 -12
- package/README.md +7 -5
- package/dist/example/demo.js +25 -25
- package/dist/example/train_base.d.ts +19 -21
- package/dist/example/train_base.js +1700 -1952
- package/dist/src/alphabet.d.ts +3 -3
- package/dist/src/alphabet.js +24 -27
- package/dist/src/alu/src/alu.d.ts +169 -194
- package/dist/src/alu/src/alu.js +374 -414
- package/dist/src/alu/src/expr.d.ts +36 -43
- package/dist/src/alu/src/expr.js +252 -278
- package/dist/src/alu/src/index.d.ts +9 -98
- package/dist/src/alu/src/index.js +10 -64
- package/dist/src/alu/src/kernel-arith.d.ts +1 -5
- package/dist/src/alu/src/kernel-arith.js +195 -285
- package/dist/src/alu/src/kernel-bits.d.ts +1 -5
- package/dist/src/alu/src/kernel-bits.js +81 -115
- package/dist/src/alu/src/kernel-logic.js +33 -63
- package/dist/src/alu/src/kernel-nd.js +155 -195
- package/dist/src/alu/src/kernel-numeric.d.ts +16 -80
- package/dist/src/alu/src/kernel-numeric.js +259 -331
- package/dist/src/alu/src/operation.d.ts +112 -132
- package/dist/src/alu/src/operation.js +149 -163
- package/dist/src/alu/src/parser.d.ts +168 -175
- package/dist/src/alu/src/parser.js +382 -421
- package/dist/src/alu/src/resonance.d.ts +16 -25
- package/dist/src/alu/src/resonance.js +49 -56
- package/dist/src/alu/src/text.d.ts +3 -7
- package/dist/src/alu/src/text.js +31 -37
- package/dist/src/alu/src/value.d.ts +14 -14
- package/dist/src/alu/src/value.js +150 -160
- package/dist/src/alu/test/alu.test.js +543 -656
- package/dist/src/bytes.d.ts +1 -5
- package/dist/src/bytes.js +33 -40
- package/dist/src/config.d.ts +99 -102
- package/dist/src/config.js +78 -83
- package/dist/src/derive/src/deduction.d.ts +60 -62
- package/dist/src/derive/src/deduction.js +103 -109
- package/dist/src/derive/src/index.d.ts +1 -7
- package/dist/src/derive/src/priority-queue.d.ts +8 -8
- package/dist/src/derive/src/priority-queue.js +57 -61
- package/dist/src/derive/src/rewrite.d.ts +15 -18
- package/dist/src/derive/src/rewrite.js +59 -67
- package/dist/src/derive/src/trie.d.ts +56 -56
- package/dist/src/derive/src/trie.js +175 -179
- package/dist/src/derive/test/derive.test.js +96 -100
- package/dist/src/extension.d.ts +13 -16
- package/dist/src/geometry.d.ts +29 -43
- package/dist/src/geometry.js +324 -268
- package/dist/src/index.d.ts +2 -17
- package/dist/src/index.js +2 -12
- package/dist/src/ingest-cache.d.ts +25 -30
- package/dist/src/ingest-cache.js +108 -127
- package/dist/src/mind/articulation.d.ts +1 -5
- package/dist/src/mind/articulation.js +77 -112
- package/dist/src/mind/attention.d.ts +40 -108
- package/dist/src/mind/attention.js +754 -872
- package/dist/src/mind/canonical.d.ts +4 -19
- package/dist/src/mind/canonical.js +27 -31
- package/dist/src/mind/graph-search.d.ts +201 -225
- package/dist/src/mind/graph-search.js +742 -821
- package/dist/src/mind/index.d.ts +2 -10
- package/dist/src/mind/junction.d.ts +31 -58
- package/dist/src/mind/junction.js +172 -237
- package/dist/src/mind/learning.d.ts +16 -52
- package/dist/src/mind/learning.js +143 -165
- package/dist/src/mind/match.d.ts +20 -69
- package/dist/src/mind/match.js +259 -318
- package/dist/src/mind/mechanisms/alu.js +16 -16
- package/dist/src/mind/mechanisms/cast.d.ts +9 -13
- package/dist/src/mind/mechanisms/cast.js +363 -456
- package/dist/src/mind/mechanisms/confluence.d.ts +8 -12
- package/dist/src/mind/mechanisms/confluence.js +152 -183
- package/dist/src/mind/mechanisms/cover.d.ts +2 -8
- package/dist/src/mind/mechanisms/cover.js +148 -210
- package/dist/src/mind/mechanisms/extraction.d.ts +8 -34
- package/dist/src/mind/mechanisms/extraction.js +234 -288
- package/dist/src/mind/mechanisms/recall.d.ts +6 -10
- package/dist/src/mind/mechanisms/recall.js +141 -185
- package/dist/src/mind/mind.d.ts +194 -155
- package/dist/src/mind/mind.js +392 -289
- package/dist/src/mind/pipeline-mechanism.d.ts +112 -124
- package/dist/src/mind/pipeline-mechanism.js +161 -172
- package/dist/src/mind/pipeline.d.ts +4 -14
- package/dist/src/mind/pipeline.js +125 -189
- package/dist/src/mind/primitives.d.ts +20 -33
- package/dist/src/mind/primitives.js +124 -120
- package/dist/src/mind/rationale.d.ts +86 -98
- package/dist/src/mind/rationale.js +113 -121
- package/dist/src/mind/reasoning.d.ts +2 -13
- package/dist/src/mind/reasoning.js +129 -166
- package/dist/src/mind/recognition.d.ts +1 -4
- package/dist/src/mind/recognition.js +198 -210
- package/dist/src/mind/resonance.d.ts +5 -22
- package/dist/src/mind/resonance.js +0 -0
- package/dist/src/mind/trace.d.ts +6 -25
- package/dist/src/mind/trace.js +50 -58
- package/dist/src/mind/traverse.d.ts +29 -58
- package/dist/src/mind/traverse.js +344 -356
- package/dist/src/mind/types.d.ts +122 -127
- package/dist/src/mind/types.js +60 -69
- package/dist/src/rabitq-ivf/src/database.d.ts +113 -0
- package/dist/src/rabitq-ivf/src/database.js +201 -0
- package/dist/src/rabitq-ivf/src/index.d.ts +7 -0
- package/dist/src/{rabitq-hnsw → rabitq-ivf}/src/index.js +1 -3
- package/dist/src/rabitq-ivf/src/ivf.d.ts +200 -0
- package/dist/src/rabitq-ivf/src/ivf.js +1165 -0
- package/dist/src/rabitq-ivf/src/prng.d.ts +19 -0
- package/dist/src/rabitq-ivf/src/prng.js +36 -0
- package/dist/src/rabitq-ivf/src/rabitq.d.ts +95 -0
- package/dist/src/rabitq-ivf/src/rabitq.js +283 -0
- package/dist/src/sema.d.ts +9 -13
- package/dist/src/sema.js +26 -40
- package/dist/src/store-sqlite.d.ts +171 -166
- package/dist/src/store-sqlite.js +768 -662
- package/dist/src/store.d.ts +597 -630
- package/dist/src/store.js +1434 -1581
- package/dist/src/vec.d.ts +5 -9
- package/dist/src/vec.js +61 -73
- package/example/train_base.ts +33 -15
- package/index.html +65 -0
- package/package.json +1 -1
- package/src/alu/README.md +1 -1
- package/src/alu/src/index.ts +1 -1
- package/src/config.ts +19 -27
- package/src/geometry.ts +93 -1
- package/src/index.ts +6 -11
- package/src/mind/attention.ts +11 -6
- package/src/mind/mechanisms/recall.ts +29 -13
- package/src/mind/mind.ts +250 -19
- package/src/mind/primitives.ts +43 -6
- package/src/mind/recognition.ts +26 -8
- package/src/mind/traverse.ts +47 -0
- package/src/mind/types.ts +20 -21
- package/src/rabitq-ivf/README.md +56 -0
- package/src/rabitq-ivf/src/database.ts +276 -0
- package/src/{rabitq-hnsw → rabitq-ivf}/src/index.ts +2 -5
- package/src/rabitq-ivf/src/ivf.ts +1330 -0
- package/src/{rabitq-hnsw → rabitq-ivf}/src/prng.ts +1 -1
- package/src/store-sqlite.ts +204 -9
- package/src/store.ts +27 -34
- package/test/08-storage.test.mjs +3 -3
- package/test/13-conversation.test.mjs +190 -20
- package/test/14-scaling.test.mjs +2 -2
- package/test/35-ivf.test.mjs +263 -0
- package/test/36-bloom.test.mjs +123 -0
- package/dist/src/rabitq-hnsw/src/database.d.ts +0 -202
- package/dist/src/rabitq-hnsw/src/database.js +0 -405
- package/dist/src/rabitq-hnsw/src/heap.d.ts +0 -22
- package/dist/src/rabitq-hnsw/src/heap.js +0 -94
- package/dist/src/rabitq-hnsw/src/hnsw.d.ts +0 -125
- package/dist/src/rabitq-hnsw/src/hnsw.js +0 -500
- package/dist/src/rabitq-hnsw/src/index.d.ts +0 -15
- package/dist/src/rabitq-hnsw/src/prng.d.ts +0 -19
- package/dist/src/rabitq-hnsw/src/prng.js +0 -38
- package/dist/src/rabitq-hnsw/src/rabitq.d.ts +0 -95
- package/dist/src/rabitq-hnsw/src/rabitq.js +0 -299
- package/dist/src/rabitq-hnsw/src/store.d.ts +0 -162
- package/dist/src/rabitq-hnsw/src/store.js +0 -916
- package/dist/src/rabitq-hnsw/test/hnsw.test.d.ts +0 -1
- package/dist/src/rabitq-hnsw/test/hnsw.test.js +0 -1197
- package/src/rabitq-hnsw/README.md +0 -303
- package/src/rabitq-hnsw/src/database.ts +0 -492
- package/src/rabitq-hnsw/src/heap.ts +0 -90
- package/src/rabitq-hnsw/src/hnsw.ts +0 -514
- package/src/rabitq-hnsw/src/store.ts +0 -994
- package/src/rabitq-hnsw/test/hnsw.test.ts +0 -1213
- /package/src/{rabitq-hnsw → rabitq-ivf}/src/rabitq.ts +0 -0
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
// that leads somewhere (has a continuation edge or a halo).
|
|
6
6
|
// segment — leaf-parent segmentation using the geometry's own groupings.
|
|
7
7
|
import { rItem } from "./trace.js";
|
|
8
|
-
import { foldTree, gistOf, perceive, resolve } from "./primitives.js";
|
|
9
|
-
import { leadsSomewhere } from "./traverse.js";
|
|
8
|
+
import { foldTree, gistOf, latin1Key, perceive, resolve, } from "./primitives.js";
|
|
9
|
+
import { atomIsHub, corpusN, leadsSomewhere } from "./traverse.js";
|
|
10
10
|
import { chainReach, leafIdAt } from "./canonical.js";
|
|
11
11
|
import { isChunk } from "../sema.js";
|
|
12
12
|
/** Decompose a byte stream into every stored form that leads somewhere
|
|
@@ -22,179 +22,170 @@ import { isChunk } from "../sema.js";
|
|
|
22
22
|
*
|
|
23
23
|
* Both O(n · maxGroup) bounded O(1) probes — never a scan of the corpus. */
|
|
24
24
|
export function recognise(ctx, bytes) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return recogniseImpl(ctx, bytes);
|
|
25
|
+
// Content-keyed memo — works for both single-turn respond() and multi-turn
|
|
26
|
+
// respondTurn() (where the map persists across calls). Skipped while
|
|
27
|
+
// tracing so every call still emits its rationale step.
|
|
28
|
+
if (ctx.recogniseMemo && !ctx.trace) {
|
|
29
|
+
const key = latin1Key(bytes);
|
|
30
|
+
const hit = ctx.recogniseMemo.get(key);
|
|
31
|
+
if (hit !== undefined)
|
|
32
|
+
return hit;
|
|
33
|
+
const fresh = recogniseImpl(ctx, bytes);
|
|
34
|
+
ctx.recogniseMemo.set(key, fresh);
|
|
35
|
+
return fresh;
|
|
36
|
+
}
|
|
37
|
+
return recogniseImpl(ctx, bytes);
|
|
39
38
|
}
|
|
40
39
|
function recogniseImpl(ctx, bytes) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
40
|
+
const store = ctx.store;
|
|
41
|
+
const sites = [];
|
|
42
|
+
const leaves = [];
|
|
43
|
+
const splits = new Set();
|
|
44
|
+
if (bytes.length === 0)
|
|
45
|
+
return { sites, leaves, splits };
|
|
46
|
+
// Span-resolve memo for THIS call: the structural pass (sub-runs inside
|
|
47
|
+
// leaf-parents) and the canonical pass (leaf-id chains) probe overlapping
|
|
48
|
+
// spans, and each resolve() is a full fold of the sub-span (fresh subarray
|
|
49
|
+
// objects — the per-response perceive memo cannot see them). Keyed
|
|
50
|
+
// numerically by (start, end); resolve is pure and the store is read-only
|
|
51
|
+
// here, so a hit is exact.
|
|
52
|
+
const spanIds = new Map();
|
|
53
|
+
const resolveSpan = (start, end) => {
|
|
54
|
+
const key = start * (bytes.length + 1) + end;
|
|
55
|
+
let id = spanIds.get(key);
|
|
56
|
+
if (id === undefined) {
|
|
57
|
+
id = resolve(ctx, bytes.subarray(start, end));
|
|
58
|
+
spanIds.set(key, id);
|
|
59
|
+
}
|
|
60
|
+
return id;
|
|
61
|
+
};
|
|
62
|
+
// Byte atoms (implicit negative-id single-byte leaves) are admitted as
|
|
63
|
+
// recognised sites only while atoms can still DISCRIMINATE at this corpus
|
|
64
|
+
// scale (see {@link atomIsHub}). On a small store a single-letter fact
|
|
65
|
+
// ("a" → "A") is genuine learnt content and its site is essential; on a
|
|
66
|
+
// large one every letter of every query would otherwise become a
|
|
67
|
+
// "recognised form" — the bridge then finds junction connectors between
|
|
68
|
+
// bare letters, cover follows edges hanging off them, and pure noise
|
|
69
|
+
// ("qq8f3kz9…") grounds to an arbitrary learnt sentence instead of
|
|
70
|
+
// silence. Atoms stay available as leaves (PASS-carried literals) and
|
|
71
|
+
// through exact tier-0 resolution regardless.
|
|
72
|
+
const atomsAreHubs = atomIsHub(ctx, corpusN(ctx));
|
|
73
|
+
const emit = (start, end, id) => {
|
|
74
|
+
if (id < 0 && atomsAreHubs)
|
|
75
|
+
return;
|
|
76
|
+
if (leadsSomewhere(ctx, id)) {
|
|
77
|
+
sites.push({ start, end, payload: id });
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
// ── structural: the query's own perceived tree ──────────────────────
|
|
81
|
+
const starts = new Set();
|
|
82
|
+
starts.add(0);
|
|
83
|
+
foldTree(ctx, perceive(ctx, bytes), 0, (n, start, end, node) => {
|
|
84
|
+
if (n.kids === null) {
|
|
85
|
+
leaves.push({ start, end, bytes: n.leaf ?? new Uint8Array(0), node });
|
|
86
|
+
}
|
|
87
|
+
if (node !== null)
|
|
88
|
+
emit(start, end, node);
|
|
89
|
+
if (isChunk(n)) {
|
|
90
|
+
starts.add(start);
|
|
91
|
+
// Try every sub-span within this leaf-parent.
|
|
92
|
+
const leafOffsets = [];
|
|
93
|
+
let off = start;
|
|
94
|
+
for (const k of n.kids) {
|
|
95
|
+
leafOffsets.push(off);
|
|
96
|
+
off += k.leaf?.length ?? 0;
|
|
97
|
+
}
|
|
98
|
+
for (let i = 0; i < n.kids.length; i++) {
|
|
99
|
+
const subIds = [];
|
|
100
|
+
for (let j = i; j < n.kids.length; j++) {
|
|
101
|
+
const kj = n.kids[j];
|
|
102
|
+
if (kj.kids !== null || !kj.leaf)
|
|
103
|
+
break;
|
|
104
|
+
const lid = store.findLeaf(kj.leaf);
|
|
105
|
+
if (lid === null)
|
|
106
|
+
break;
|
|
107
|
+
subIds.push(lid);
|
|
108
|
+
const branch = store.findBranch(subIds);
|
|
109
|
+
if (branch === null)
|
|
110
|
+
continue;
|
|
111
|
+
const subEnd = leafOffsets[j] + (kj.leaf?.length ?? 0);
|
|
112
|
+
const resolved = resolveSpan(leafOffsets[i], subEnd);
|
|
113
|
+
if (resolved !== null)
|
|
114
|
+
emit(leafOffsets[i], subEnd, resolved);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
// ── canonical: longest-known-leaf re-segmentation ──────────────────
|
|
120
|
+
const W = ctx.space.maxGroup;
|
|
121
|
+
const singleLeaf = new Array(bytes.length).fill(null);
|
|
122
|
+
for (let p = 0; p < bytes.length; p++) {
|
|
123
|
+
const id = leafIdAt(ctx, bytes, p);
|
|
124
|
+
if (id !== null)
|
|
125
|
+
singleLeaf[p] = { id, end: p + 1 };
|
|
126
|
+
}
|
|
127
|
+
const leafFrom = (p) => {
|
|
128
|
+
if (p >= bytes.length)
|
|
129
|
+
return null;
|
|
130
|
+
return singleLeaf[p];
|
|
131
|
+
};
|
|
132
|
+
const chunkEnd = new Uint32Array(bytes.length);
|
|
133
|
+
const sorted = [...starts].sort((a, b) => a - b);
|
|
134
|
+
for (let si = 0; si < sorted.length; si++) {
|
|
135
|
+
const chunkStart = sorted[si];
|
|
136
|
+
const chunkLimit = si + 1 < sorted.length ? sorted[si + 1] : bytes.length;
|
|
137
|
+
for (let p = chunkStart; p < chunkLimit; p++) {
|
|
138
|
+
chunkEnd[p] = chunkLimit;
|
|
109
139
|
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
// ── canonical: longest-known-leaf re-segmentation ──────────────────
|
|
114
|
-
const W = ctx.space.maxGroup;
|
|
115
|
-
const singleLeaf = new Array(bytes.length).fill(null);
|
|
116
|
-
for (let p = 0; p < bytes.length; p++) {
|
|
117
|
-
const id = leafIdAt(ctx, bytes, p);
|
|
118
|
-
if (id !== null) {
|
|
119
|
-
singleLeaf[p] = { id, end: p + 1 };
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
const leafFrom = (p) => {
|
|
123
|
-
if (p >= bytes.length) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
return singleLeaf[p];
|
|
127
|
-
};
|
|
128
|
-
const chunkEnd = new Uint32Array(bytes.length);
|
|
129
|
-
const sorted = [...starts].sort((a, b) => a - b);
|
|
130
|
-
for (let si = 0; si < sorted.length; si++) {
|
|
131
|
-
const chunkStart = sorted[si];
|
|
132
|
-
const chunkLimit = si + 1 < sorted.length ? sorted[si + 1] : bytes.length;
|
|
133
|
-
for (let p = chunkStart; p < chunkLimit; p++) {
|
|
134
|
-
chunkEnd[p] = chunkLimit;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
const tryChain = (p, maxIds) => {
|
|
138
|
-
const first = leafFrom(p);
|
|
139
|
-
if (!first) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
emit(p, first.end, first.id);
|
|
143
|
-
const ids = [first.id];
|
|
144
|
-
let pos = first.end;
|
|
145
|
-
let prevId = null;
|
|
146
|
-
for (let depth = 1; pos < bytes.length && ids.length <= maxIds; depth++) {
|
|
147
|
-
const nx = leafFrom(pos);
|
|
148
|
-
if (!nx) {
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
ids.push(nx.id);
|
|
152
|
-
pos = nx.end;
|
|
153
|
-
if (store.findBranch(ids) === null) {
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
const id = resolveSpan(p, pos);
|
|
157
|
-
if (id === null || id === prevId) {
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
prevId = id;
|
|
161
|
-
emit(p, pos, id);
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
for (let p = 0; p < bytes.length; p++) {
|
|
165
|
-
if (starts.has(p)) {
|
|
166
|
-
tryChain(p, chainReach(W)); // boundary start — full reach
|
|
167
|
-
} else {
|
|
168
|
-
const limit = chunkEnd[p] + W;
|
|
169
|
-
tryChain(p, Math.min(limit - p, chainReach(W)));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
// ── splits: a form boundary that does not fall on a leaf edge ────────
|
|
173
|
-
const leafEdges = new Set([bytes.length]);
|
|
174
|
-
for (const lf of leaves) {
|
|
175
|
-
leafEdges.add(lf.start);
|
|
176
|
-
}
|
|
177
|
-
for (const s of sites) {
|
|
178
|
-
if (!leafEdges.has(s.start)) {
|
|
179
|
-
splits.add(s.start);
|
|
180
140
|
}
|
|
181
|
-
|
|
182
|
-
|
|
141
|
+
const tryChain = (p, maxIds) => {
|
|
142
|
+
const first = leafFrom(p);
|
|
143
|
+
if (!first)
|
|
144
|
+
return;
|
|
145
|
+
emit(p, first.end, first.id);
|
|
146
|
+
const ids = [first.id];
|
|
147
|
+
let pos = first.end;
|
|
148
|
+
let prevId = null;
|
|
149
|
+
for (let depth = 1; pos < bytes.length && ids.length <= maxIds; depth++) {
|
|
150
|
+
const nx = leafFrom(pos);
|
|
151
|
+
if (!nx)
|
|
152
|
+
break;
|
|
153
|
+
ids.push(nx.id);
|
|
154
|
+
pos = nx.end;
|
|
155
|
+
if (store.findBranch(ids) === null)
|
|
156
|
+
continue;
|
|
157
|
+
const id = resolveSpan(p, pos);
|
|
158
|
+
if (id === null || id === prevId)
|
|
159
|
+
continue;
|
|
160
|
+
prevId = id;
|
|
161
|
+
emit(p, pos, id);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
for (let p = 0; p < bytes.length; p++) {
|
|
165
|
+
if (starts.has(p)) {
|
|
166
|
+
tryChain(p, chainReach(W)); // boundary start — full reach
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const limit = chunkEnd[p] + W;
|
|
170
|
+
tryChain(p, Math.min(limit - p, chainReach(W)));
|
|
171
|
+
}
|
|
183
172
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
173
|
+
// ── splits: a form boundary that does not fall on a leaf edge ────────
|
|
174
|
+
const leafEdges = new Set([bytes.length]);
|
|
175
|
+
for (const lf of leaves)
|
|
176
|
+
leafEdges.add(lf.start);
|
|
177
|
+
for (const s of sites) {
|
|
178
|
+
if (!leafEdges.has(s.start))
|
|
179
|
+
splits.add(s.start);
|
|
180
|
+
if (!leafEdges.has(s.end))
|
|
181
|
+
splits.add(s.end);
|
|
182
|
+
}
|
|
183
|
+
ctx.trace?.step("recognise", [rItem(bytes, "query")], sites.map((s) => rItem(bytes.subarray(s.start, s.end), "form", s.payload, [
|
|
190
184
|
s.start,
|
|
191
185
|
s.end,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
` (over ${leaves.length} perceived leaves)`,
|
|
196
|
-
);
|
|
197
|
-
return { sites, leaves, splits };
|
|
186
|
+
])), `decompose the query into ${sites.length} learnt form(s) that lead somewhere` +
|
|
187
|
+
` (over ${leaves.length} perceived leaves)`);
|
|
188
|
+
return { sites, leaves, splits };
|
|
198
189
|
}
|
|
199
190
|
/** Segment bytes using the geometry's own groupings — leaf-parent
|
|
200
191
|
* nodes from the perceived tree, with consecutive bare leaves merged
|
|
@@ -202,47 +193,44 @@ function recogniseImpl(ctx, bytes) {
|
|
|
202
193
|
* IN ISOLATION, so the same content has the same gist regardless of
|
|
203
194
|
* where it appears. */
|
|
204
195
|
export function segment(ctx, bytes) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
196
|
+
const tree = perceive(ctx, bytes);
|
|
197
|
+
const out = [];
|
|
198
|
+
let pendingStart = -1;
|
|
199
|
+
let pendingEnd = -1;
|
|
200
|
+
const flush = () => {
|
|
201
|
+
if (pendingStart >= 0 && pendingEnd > pendingStart) {
|
|
202
|
+
out.push({
|
|
203
|
+
start: pendingStart,
|
|
204
|
+
end: pendingEnd,
|
|
205
|
+
v: gistOf(ctx, bytes.subarray(pendingStart, pendingEnd)),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
pendingStart = -1;
|
|
209
|
+
pendingEnd = -1;
|
|
210
|
+
};
|
|
211
|
+
const walk = (n, start) => {
|
|
212
|
+
if (n.kids === null) {
|
|
213
|
+
const end = start + (n.leaf?.length ?? 0);
|
|
214
|
+
if (pendingStart < 0)
|
|
215
|
+
pendingStart = start;
|
|
216
|
+
pendingEnd = end;
|
|
217
|
+
return end;
|
|
218
|
+
}
|
|
219
|
+
if (isChunk(n)) {
|
|
220
|
+
flush();
|
|
221
|
+
let end = start;
|
|
222
|
+
for (const c of n.kids)
|
|
223
|
+
end += c.leaf?.length ?? 0;
|
|
224
|
+
out.push({ start, end, v: gistOf(ctx, bytes.subarray(start, end)) });
|
|
225
|
+
return end;
|
|
226
|
+
}
|
|
227
|
+
flush();
|
|
228
|
+
let pos = start;
|
|
229
|
+
for (const c of n.kids)
|
|
230
|
+
pos = walk(c, pos);
|
|
231
|
+
return pos;
|
|
232
|
+
};
|
|
233
|
+
walk(tree, 0);
|
|
238
234
|
flush();
|
|
239
|
-
|
|
240
|
-
for (const c of n.kids) {
|
|
241
|
-
pos = walk(c, pos);
|
|
242
|
-
}
|
|
243
|
-
return pos;
|
|
244
|
-
};
|
|
245
|
-
walk(tree, 0);
|
|
246
|
-
flush();
|
|
247
|
-
return out;
|
|
235
|
+
return out;
|
|
248
236
|
}
|
|
@@ -2,12 +2,7 @@ import type { MindContext } from "./types.js";
|
|
|
2
2
|
/** The connector that belongs BETWEEN two adjacent results — the graded
|
|
3
3
|
* junction ladder described in the module note above. Returns null when
|
|
4
4
|
* the graph holds no evidence that the two ever ran together. */
|
|
5
|
-
export declare function bridge(
|
|
6
|
-
ctx: MindContext,
|
|
7
|
-
left: Uint8Array,
|
|
8
|
-
right: Uint8Array,
|
|
9
|
-
interiorAllowance?: number,
|
|
10
|
-
): Promise<Uint8Array | null>;
|
|
5
|
+
export declare function bridge(ctx: MindContext, left: Uint8Array, right: Uint8Array, interiorAllowance?: number): Promise<Uint8Array | null>;
|
|
11
6
|
/** Join two spans with the learnt connector between them, when one exists —
|
|
12
7
|
* the composition step every out-of-search assembly (multi-topic fusion,
|
|
13
8
|
* CAST's substitution and comparison) shares. A miss joins the pieces BARE
|
|
@@ -15,26 +10,14 @@ export declare function bridge(
|
|
|
15
10
|
* so a degraded join is visible in the rationale regardless of which
|
|
16
11
|
* mechanism paid it. (The in-search connector splice in graph-search.ts is
|
|
17
12
|
* the same concept inside the deduction, where the join is a costed rule.) */
|
|
18
|
-
export declare function joinWithBridge(
|
|
19
|
-
ctx: MindContext,
|
|
20
|
-
left: Uint8Array,
|
|
21
|
-
right: Uint8Array,
|
|
22
|
-
): Promise<Uint8Array>;
|
|
13
|
+
export declare function joinWithBridge(ctx: MindContext, left: Uint8Array, right: Uint8Array): Promise<Uint8Array>;
|
|
23
14
|
/** The pivot a produced answer bridges through: the longest UNCONSUMED learnt
|
|
24
15
|
* CONTEXT (a node bearing a continuation edge) whose bytes `answer` literally
|
|
25
16
|
* contains. Candidates are gathered by resonating the answer's sub-regions
|
|
26
17
|
* (breadth-first, leaves skipped, probes capped by branch count), then
|
|
27
18
|
* confirmed by exact byte containment — a near-resonance alone never hops. */
|
|
28
|
-
export declare function pivotInto(
|
|
29
|
-
|
|
30
|
-
answer: Uint8Array,
|
|
31
|
-
consumed: ReadonlySet<number>,
|
|
32
|
-
): Promise<number | null>;
|
|
33
|
-
export declare function meaningOf(
|
|
34
|
-
ctx: MindContext,
|
|
35
|
-
bytes: Uint8Array,
|
|
36
|
-
anchors: ReadonlyArray<{
|
|
19
|
+
export declare function pivotInto(ctx: MindContext, answer: Uint8Array, consumed: ReadonlySet<number>): Promise<number | null>;
|
|
20
|
+
export declare function meaningOf(ctx: MindContext, bytes: Uint8Array, anchors: ReadonlyArray<{
|
|
37
21
|
name: string;
|
|
38
22
|
form: Uint8Array;
|
|
39
|
-
|
|
40
|
-
): Promise<string | null>;
|
|
23
|
+
}>): Promise<string | null>;
|
|
Binary file
|
package/dist/src/mind/trace.d.ts
CHANGED
|
@@ -1,34 +1,15 @@
|
|
|
1
1
|
import type { MindContext } from "./types.js";
|
|
2
2
|
import type { DerivationStep } from "./graph-search.js";
|
|
3
3
|
import type { RationaleItem } from "./rationale.js";
|
|
4
|
-
export declare function rItem(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
node?: number,
|
|
8
|
-
span?: [number, number],
|
|
9
|
-
): RationaleItem;
|
|
10
|
-
export declare function rNode(
|
|
11
|
-
ctx: MindContext,
|
|
12
|
-
id: number,
|
|
13
|
-
role?: string,
|
|
14
|
-
score?: number,
|
|
15
|
-
): RationaleItem;
|
|
16
|
-
export declare function rDeriv(
|
|
17
|
-
ctx: MindContext,
|
|
18
|
-
it: DerivationStep["conclusion"],
|
|
19
|
-
role?: string,
|
|
20
|
-
): RationaleItem;
|
|
4
|
+
export declare function rItem(bytes: Uint8Array, role?: string, node?: number, span?: [number, number]): RationaleItem;
|
|
5
|
+
export declare function rNode(ctx: MindContext, id: number, role?: string, score?: number): RationaleItem;
|
|
6
|
+
export declare function rDeriv(ctx: MindContext, it: DerivationStep["conclusion"], role?: string): RationaleItem;
|
|
21
7
|
/** The standard FALL-THROUGH closer every self-gating mechanism ends with:
|
|
22
8
|
* close the open scope with no outputs and the reason, and return null so
|
|
23
9
|
* the caller can `return fail("…")` in one expression. `t` is the scope an
|
|
24
10
|
* enclosing `ctx.trace?.enter(...)` returned (undefined when not tracing). */
|
|
25
|
-
export declare function traceFail(
|
|
26
|
-
t: {
|
|
11
|
+
export declare function traceFail(t: {
|
|
27
12
|
done(outputs: RationaleItem[], note?: string): void;
|
|
28
|
-
|
|
29
|
-
): (note: string) => null;
|
|
13
|
+
} | undefined): (note: string) => null;
|
|
30
14
|
export declare const MOVE_NOTE: Record<string, string>;
|
|
31
|
-
export declare function traceDerivation(
|
|
32
|
-
ctx: MindContext,
|
|
33
|
-
steps: ReadonlyArray<DerivationStep>,
|
|
34
|
-
): void;
|
|
15
|
+
export declare function traceDerivation(ctx: MindContext, steps: ReadonlyArray<DerivationStep>): void;
|
package/dist/src/mind/trace.js
CHANGED
|
@@ -6,76 +6,68 @@
|
|
|
6
6
|
import { read } from "./primitives.js";
|
|
7
7
|
import { decodeText } from "./rationale.js";
|
|
8
8
|
export function rItem(bytes, role, node, span) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
return {
|
|
10
|
+
text: decodeText(bytes),
|
|
11
|
+
role,
|
|
12
|
+
node: node ?? undefined,
|
|
13
|
+
span,
|
|
14
|
+
};
|
|
15
15
|
}
|
|
16
16
|
export function rNode(ctx, id, role, score) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
return {
|
|
18
|
+
text: decodeText(read(ctx, id)),
|
|
19
|
+
node: id,
|
|
20
|
+
role,
|
|
21
|
+
score,
|
|
22
|
+
};
|
|
23
23
|
}
|
|
24
24
|
export function rDeriv(ctx, it, role) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
const text = it.bytes
|
|
26
|
+
? decodeText(it.bytes)
|
|
27
|
+
: it.node !== undefined
|
|
28
|
+
? decodeText(read(ctx, it.node))
|
|
29
|
+
: it.kind === "cover"
|
|
30
|
+
? `cover@${it.span[0]}`
|
|
31
|
+
: `[${it.span[0]},${it.span[1]})`;
|
|
32
|
+
return { text, role: role ?? it.kind, node: it.node, span: it.span };
|
|
33
33
|
}
|
|
34
34
|
/** The standard FALL-THROUGH closer every self-gating mechanism ends with:
|
|
35
35
|
* close the open scope with no outputs and the reason, and return null so
|
|
36
36
|
* the caller can `return fail("…")` in one expression. `t` is the scope an
|
|
37
37
|
* enclosing `ctx.trace?.enter(...)` returned (undefined when not tracing). */
|
|
38
38
|
export function traceFail(t) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
return (note) => {
|
|
40
|
+
t?.done([], note);
|
|
41
|
+
return null;
|
|
42
|
+
};
|
|
43
43
|
}
|
|
44
44
|
export const MOVE_NOTE = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
"step": "a derivation step",
|
|
45
|
+
"follow-edge": "follow a learned continuation edge — 'what follows what'",
|
|
46
|
+
"concept-hop": "jump a concept (halo) link — a synonym's edge",
|
|
47
|
+
"voice": "emit the asker's own wording for this form (articulation)",
|
|
48
|
+
"ground": "a chain reached its terminal answer",
|
|
49
|
+
"splice-connector": "splice a learnt connector between two rewrites",
|
|
50
|
+
"split": "cut a span at a sub-leaf form boundary so a form can be reached",
|
|
51
|
+
"fuse": "fuse adjacent fragments toward a deeper learned form",
|
|
52
|
+
"recompose": "recompose fused parts into a learned whole that leads on",
|
|
53
|
+
"bridge": "advance the cover frontier across this span",
|
|
54
|
+
"pool-vote": "pool independent regions' evidence for a shared anchor (sum, not shortest path)",
|
|
55
|
+
"axiom": "a seed: a perceived leaf, recognised form, or computed result",
|
|
56
|
+
"step": "a derivation step",
|
|
58
57
|
};
|
|
59
58
|
export function traceDerivation(ctx, steps) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
premises,
|
|
75
|
-
conclusion,
|
|
76
|
-
s.cost > 0 ? `${note} (cost ${s.cost})` : note,
|
|
77
|
-
deps.length > 0 ? deps : undefined,
|
|
78
|
-
);
|
|
79
|
-
indexOfOrder.set(s.order, index);
|
|
80
|
-
}
|
|
59
|
+
const t = ctx.trace;
|
|
60
|
+
if (!t)
|
|
61
|
+
return;
|
|
62
|
+
const indexOfOrder = new Map();
|
|
63
|
+
for (const s of steps) {
|
|
64
|
+
const note = MOVE_NOTE[s.move] ?? s.move;
|
|
65
|
+
const deps = s.producers
|
|
66
|
+
.map((o) => indexOfOrder.get(o))
|
|
67
|
+
.filter((x) => x !== undefined);
|
|
68
|
+
const premises = s.premises.map((p) => rDeriv(ctx, p));
|
|
69
|
+
const conclusion = [rDeriv(ctx, s.conclusion)];
|
|
70
|
+
const index = t.step(s.move, premises, conclusion, s.cost > 0 ? `${note} (cost ${s.cost})` : note, deps.length > 0 ? deps : undefined);
|
|
71
|
+
indexOfOrder.set(s.order, index);
|
|
72
|
+
}
|
|
81
73
|
}
|