@hviana/sema 0.9.0 → 0.9.2
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 +7 -7
- package/dist/src/alu/src/index.d.ts +1 -1
- package/dist/src/alu/src/index.js +1 -1
- package/dist/src/alu/src/parser.js +2 -6
- package/dist/src/alu/src/resonance.d.ts +13 -0
- package/dist/src/alu/src/resonance.js +41 -0
- package/dist/src/alu/test/alu.test.js +39 -0
- package/dist/src/bytes.d.ts +6 -2
- package/dist/src/bytes.js +10 -4
- package/dist/src/canon.js +44 -0
- package/dist/src/geometry.d.ts +19 -1
- package/dist/src/geometry.js +125 -141
- package/dist/src/meter.d.ts +33 -0
- package/dist/src/meter.js +34 -1
- package/dist/src/mind/articulation.js +14 -1
- package/dist/src/mind/attention.d.ts +12 -0
- package/dist/src/mind/attention.js +44 -16
- package/dist/src/mind/bridge.js +3 -3
- package/dist/src/mind/derivation.d.ts +40 -0
- package/dist/src/mind/derivation.js +34 -0
- package/dist/src/mind/evidence.d.ts +24 -0
- package/dist/src/mind/evidence.js +90 -0
- package/dist/src/mind/graph-search.d.ts +89 -15
- package/dist/src/mind/graph-search.js +345 -174
- package/dist/src/mind/learning.js +1 -1
- package/dist/src/mind/mechanisms/cover.d.ts +19 -3
- package/dist/src/mind/mechanisms/cover.js +142 -61
- package/dist/src/mind/mechanisms/recall.js +10 -3
- package/dist/src/mind/mind.d.ts +6 -0
- package/dist/src/mind/mind.js +5 -2
- package/dist/src/mind/pipeline.d.ts +5 -1
- package/dist/src/mind/pipeline.js +220 -90
- package/dist/src/mind/primitives.d.ts +25 -5
- package/dist/src/mind/primitives.js +107 -44
- package/dist/src/mind/reasoning.d.ts +18 -4
- package/dist/src/mind/reasoning.js +487 -328
- package/dist/src/mind/recognition.js +29 -13
- package/dist/src/mind/resonance.js +1 -11
- package/dist/src/mind/traverse.d.ts +45 -5
- package/dist/src/mind/traverse.js +285 -8
- package/dist/src/mind/types.d.ts +16 -1
- package/dist/src/store-sqlite.d.ts +25 -0
- package/dist/src/store-sqlite.js +89 -1
- package/dist/src/store.d.ts +48 -4
- package/dist/src/store.js +86 -6
- package/docs/INDEX.md +20 -19
- package/docs/INVARIANTS.md +17 -16
- package/docs/architecture/bounded-reads.md +1 -1
- package/docs/architecture/caches.md +5 -4
- package/docs/architecture/closure.md +45 -5
- package/docs/architecture/cost-model.md +16 -0
- package/docs/architecture/evidence.md +113 -0
- package/docs/architecture/exact-vs-approximate.md +10 -9
- package/docs/architecture/factored-machinery.md +14 -13
- package/docs/architecture/fold-contract.md +51 -1
- package/docs/architecture/mechanism-market.md +21 -0
- package/docs/architecture/memoization.md +3 -3
- package/docs/architecture/meter.md +2 -1
- package/docs/architecture/saturation.md +12 -0
- package/docs/architecture/store.md +25 -2
- package/docs/failures/tempting-but-wrong.md +13 -2
- package/docs/harness/gates.md +12 -10
- package/docs/mechanisms/cover.md +23 -6
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/alu/README.md +10 -2
- package/src/alu/src/index.ts +1 -0
- package/src/alu/src/parser.ts +6 -6
- package/src/alu/src/resonance.ts +42 -0
- package/src/alu/test/alu.test.ts +40 -0
- package/src/bytes.ts +13 -3
- package/src/canon.ts +40 -0
- package/src/geometry.ts +183 -154
- package/src/meter.ts +34 -1
- package/src/mind/articulation.ts +14 -2
- package/src/mind/attention.ts +47 -25
- package/src/mind/bridge.ts +3 -3
- package/src/mind/derivation.ts +77 -0
- package/src/mind/evidence.ts +107 -0
- package/src/mind/graph-search.ts +449 -221
- package/src/mind/learning.ts +1 -7
- package/src/mind/match.ts +1 -2
- package/src/mind/mechanisms/cast.ts +1 -2
- package/src/mind/mechanisms/cover.ts +207 -87
- package/src/mind/mechanisms/extraction.ts +1 -2
- package/src/mind/mechanisms/prefix-completion.ts +1 -1
- package/src/mind/mechanisms/recall.ts +17 -5
- package/src/mind/mechanisms/reference.ts +1 -1
- package/src/mind/mind.ts +9 -30
- package/src/mind/pipeline.ts +263 -104
- package/src/mind/primitives.ts +119 -43
- package/src/mind/reasoning.ts +611 -419
- package/src/mind/recognition.ts +24 -9
- package/src/mind/resonance.ts +2 -16
- package/src/mind/trace.ts +1 -1
- package/src/mind/traverse.ts +321 -8
- package/src/mind/types.ts +15 -11
- package/src/store-sqlite.ts +92 -1
- package/src/store.ts +113 -7
- package/test/105-derive-through-reports-its-refusal.test.mjs +8 -5
- package/test/106-the-join-fires.test.mjs +21 -0
- package/test/111-the-cover-assembly-is-counted.test.mjs +8 -5
- package/test/128-the-leads-somewhere-pair-agrees.test.mjs +18 -12
- package/test/136-the-two-named-limits.test.mjs +3 -2
- package/test/137-the-law-lives-once-and-below.test.mjs +21 -0
- package/test/148-exact-shortcuts-agree.test.mjs +188 -0
- package/test/149-the-closure-engine.test.mjs +138 -0
- package/test/150-the-join-is-output-sensitive.test.mjs +66 -0
- package/test/151-the-cover-pays-for-what-it-reaches.test.mjs +142 -0
- package/test/152-the-read-side-names-as-the-write-side.test.mjs +146 -0
- package/test/153-a-cheaper-bound-is-looked-at-first.test.mjs +155 -0
- package/test/154-the-question-names-the-step.test.mjs +281 -0
- package/test/24-generalization.test.mjs +32 -0
- package/test/36-bloom.test.mjs +53 -0
- package/test/37-cluster-dispersion-fusion.test.mjs +75 -0
- package/test/48-recognise-turn-connective.test.mjs +3 -2
- package/test/55-cost-meter.test.mjs +4 -4
- package/test/90-connector-read-cap.test.mjs +7 -7
package/src/mind/learning.ts
CHANGED
|
@@ -7,13 +7,7 @@ import { addInto, normalize, Vec, zeros } from "../vec.js";
|
|
|
7
7
|
import { bindSeat, companySignature, isChunk, Sema } from "../sema.js";
|
|
8
8
|
import type { Input, MindContext } from "./types.js";
|
|
9
9
|
import { changedNodes } from "./types.js";
|
|
10
|
-
import {
|
|
11
|
-
inputBytes,
|
|
12
|
-
latin1Key,
|
|
13
|
-
perceive,
|
|
14
|
-
perceiveDeposit,
|
|
15
|
-
resolve,
|
|
16
|
-
} from "./primitives.js";
|
|
10
|
+
import { inputBytes, perceiveDeposit, resolve } from "./primitives.js";
|
|
17
11
|
import { canonicalWindows, leafIdPrefix } from "./canonical.js";
|
|
18
12
|
import { rItem, rNode } from "./trace.js";
|
|
19
13
|
import { hubBound } from "./traverse.js";
|
package/src/mind/match.ts
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
} from "../geometry.js";
|
|
41
41
|
import { bytesEqual, indexOf, latin1 } from "../bytes.js";
|
|
42
42
|
import type { MindContext } from "./types.js";
|
|
43
|
-
import {
|
|
43
|
+
import { leafIdRun } from "./canonical.js";
|
|
44
44
|
import { foldTree, gistOf, perceive, read, resolve } from "./primitives.js";
|
|
45
45
|
import {
|
|
46
46
|
argmaxCosine,
|
|
@@ -54,7 +54,6 @@ import {
|
|
|
54
54
|
sharedReachMemo,
|
|
55
55
|
} from "./traverse.js";
|
|
56
56
|
import { recognise, segment } from "./recognition.js";
|
|
57
|
-
import { rItem } from "./trace.js";
|
|
58
57
|
import type { Site } from "./graph-search.js";
|
|
59
58
|
|
|
60
59
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -31,9 +31,8 @@ import {
|
|
|
31
31
|
} from "../match.js";
|
|
32
32
|
import { joinWithBridge } from "../resonance.js";
|
|
33
33
|
import { CONCEPT, STEP } from "../graph-search.js";
|
|
34
|
-
import {
|
|
34
|
+
import { indexOf } from "../../bytes.js";
|
|
35
35
|
import { consensusFloor, dominates } from "../../geometry.js";
|
|
36
|
-
import { decodeText } from "../rationale.js";
|
|
37
36
|
import { restates, unexplainedSpans } from "../derivation.js";
|
|
38
37
|
import { rItem, rNode } from "../trace.js";
|
|
39
38
|
import { dismissedKnownContent } from "../bridge.js";
|
|
@@ -10,55 +10,91 @@
|
|
|
10
10
|
// ordinary admissible-floor check, with no extension special-case anywhere.
|
|
11
11
|
|
|
12
12
|
import type { MindContext } from "../types.js";
|
|
13
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
ComputedResult,
|
|
15
|
+
ConceptLicence,
|
|
16
|
+
ConnectorLicence,
|
|
17
|
+
DerivationStep,
|
|
18
|
+
Site,
|
|
19
|
+
} from "../graph-search.js";
|
|
14
20
|
import { read, resolve } from "../primitives.js";
|
|
15
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
guidedFirst,
|
|
23
|
+
hubBound,
|
|
24
|
+
namedContinuations,
|
|
25
|
+
scaffoldSpans,
|
|
26
|
+
} from "../traverse.js";
|
|
16
27
|
import { conceptHop } from "../match.js";
|
|
17
28
|
import { bridge } from "../resonance.js";
|
|
18
29
|
import { liftAnswer, liftedScaffolding, segRestatesQuery } from "../types.js";
|
|
19
30
|
import { decodeText } from "../rationale.js";
|
|
20
31
|
import { insideAnsweredTurn, restates } from "../derivation.js";
|
|
21
|
-
import { indexOf } from "../../bytes.js";
|
|
22
32
|
import type { RationaleItem } from "../rationale.js";
|
|
23
33
|
import { rItem, rNode, traceDerivation } from "../trace.js";
|
|
24
34
|
import type { PipelineMechanism } from "../pipeline-mechanism.js";
|
|
25
35
|
|
|
26
36
|
// ── Concept / connector pre-resolution ──────────────────────────────────────
|
|
27
37
|
|
|
28
|
-
|
|
38
|
+
/** The concept hops the cover may take, OFFERED up front and looked up only
|
|
39
|
+
* when the search asks (see {@link Licence}): every recognised form with no
|
|
40
|
+
* continuation of its own may borrow a halo sibling's. */
|
|
41
|
+
export interface CoverConcepts extends ConceptLicence {
|
|
42
|
+
/** Look up the asked forms' concept targets not yet granted. */
|
|
43
|
+
grant(nodes: Iterable<number>): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function offerConcepts(
|
|
29
47
|
ctx: MindContext,
|
|
30
|
-
sites: Site
|
|
31
|
-
):
|
|
32
|
-
const
|
|
33
|
-
const visited = new Set<number>();
|
|
48
|
+
sites: ReadonlyArray<Site>,
|
|
49
|
+
): CoverConcepts {
|
|
50
|
+
const offered = new Set<number>();
|
|
34
51
|
for (const { payload: n } of sites) {
|
|
35
|
-
if (
|
|
36
|
-
visited.add(n);
|
|
37
|
-
if (ctx.store.hasNext(n)) continue;
|
|
38
|
-
const hop = await conceptHop(ctx, n);
|
|
39
|
-
if (hop !== null) target.set(n, hop);
|
|
40
|
-
}
|
|
41
|
-
if (target.size > 0) {
|
|
42
|
-
ctx.trace?.step(
|
|
43
|
-
"resolveConcepts",
|
|
44
|
-
[...target.keys()].map((n) => rNode(ctx, n, "edgeless-form")),
|
|
45
|
-
[...target.values()].map((h) => rNode(ctx, h, "concept-sibling")),
|
|
46
|
-
"borrow a synonym's continuation edge for each edge-less form (a concept/halo hop)",
|
|
47
|
-
);
|
|
52
|
+
if (!offered.has(n) && !ctx.store.hasNext(n)) offered.add(n);
|
|
48
53
|
}
|
|
49
|
-
|
|
54
|
+
const granted = new Map<number, number | null>();
|
|
55
|
+
return {
|
|
56
|
+
offered,
|
|
57
|
+
granted,
|
|
58
|
+
asked: new Set(),
|
|
59
|
+
async grant(nodes) {
|
|
60
|
+
const found: Array<[number, number]> = [];
|
|
61
|
+
for (const n of nodes) {
|
|
62
|
+
if (granted.has(n)) continue;
|
|
63
|
+
const hop = await conceptHop(ctx, n);
|
|
64
|
+
granted.set(n, hop);
|
|
65
|
+
if (hop !== null) found.push([n, hop]);
|
|
66
|
+
}
|
|
67
|
+
if (found.length > 0) {
|
|
68
|
+
ctx.trace?.step(
|
|
69
|
+
"resolveConcepts",
|
|
70
|
+
found.map(([n]) => rNode(ctx, n, "edgeless-form")),
|
|
71
|
+
found.map(([, h]) => rNode(ctx, h, "concept-sibling")),
|
|
72
|
+
"borrow a synonym's continuation edge for each edge-less form the search reached (a concept/halo hop)",
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The connectors the cover may splice, OFFERED up front and BRIDGED only when
|
|
80
|
+
* the search asks (see {@link ConnectorLicence}): every pair a learnt whole
|
|
81
|
+
* could run together — two touching sites, each side as itself or as its
|
|
82
|
+
* answer, in both orders — and, when three or more answers are recognised, the
|
|
83
|
+
* first answer to each later one (the N-ary whole). */
|
|
84
|
+
export interface CoverConnectors extends ConnectorLicence {
|
|
85
|
+
/** Bridge the asked pairs not yet granted. */
|
|
86
|
+
grant(keys: Iterable<string>): Promise<void>;
|
|
50
87
|
}
|
|
51
88
|
|
|
52
|
-
export
|
|
89
|
+
export function offerConnectors(
|
|
53
90
|
ctx: MindContext,
|
|
54
91
|
sites: ReadonlyArray<Site>,
|
|
55
92
|
query?: Uint8Array,
|
|
56
|
-
):
|
|
57
|
-
const links = new Map<string, Uint8Array>();
|
|
93
|
+
): CoverConnectors {
|
|
58
94
|
const answerOf = (n: number) => guidedFirst(ctx, n) ?? n;
|
|
59
95
|
// A site's continuation already present elsewhere in the query is stale
|
|
60
96
|
// transcript evidence: cover still needs the site for structural context,
|
|
61
|
-
// but liftAnswer will trim that continuation as already answered.
|
|
97
|
+
// but liftAnswer will trim that continuation as already answered. Offering
|
|
62
98
|
// pairwise/n-ary bridges for it can only create connectors that are later
|
|
63
99
|
// discarded — a semantically neutral gate (it removes work whose product
|
|
64
100
|
// liftAnswer throws away), and a cumulative (multi-turn) query is exactly
|
|
@@ -98,20 +134,16 @@ export async function resolveConnectors(
|
|
|
98
134
|
return restates(query, bytes, 0);
|
|
99
135
|
});
|
|
100
136
|
});
|
|
101
|
-
const
|
|
102
|
-
if (l === r || links.has(l + "," + r)) return;
|
|
103
|
-
if (ctx.meter) ctx.meter.coverBridges++;
|
|
104
|
-
const link = await bridge(ctx, read(ctx, l), read(ctx, r));
|
|
105
|
-
if (link !== null) links.set(l + "," + r, link);
|
|
106
|
-
};
|
|
137
|
+
const pairwise = new Set<string>();
|
|
107
138
|
for (let i = 0; i + 1 < ordered.length; i++) {
|
|
108
139
|
if (ordered[i].end !== ordered[i + 1].start) continue;
|
|
109
140
|
const lefts = [ordered[i].payload, answerOf(ordered[i].payload)];
|
|
110
141
|
const rights = [ordered[i + 1].payload, answerOf(ordered[i + 1].payload)];
|
|
111
142
|
for (const l of new Set(lefts)) {
|
|
112
143
|
for (const r of new Set(rights)) {
|
|
113
|
-
|
|
114
|
-
|
|
144
|
+
if (l === r) continue;
|
|
145
|
+
pairwise.add(l + "," + r);
|
|
146
|
+
pairwise.add(r + "," + l);
|
|
115
147
|
}
|
|
116
148
|
}
|
|
117
149
|
}
|
|
@@ -123,46 +155,70 @@ export async function resolveConnectors(
|
|
|
123
155
|
seenN.add(node);
|
|
124
156
|
orderedNodes.push({ node, bytes: read(ctx, node) });
|
|
125
157
|
}
|
|
158
|
+
const nary = new Map<
|
|
159
|
+
string,
|
|
160
|
+
{ left: Uint8Array; right: Uint8Array; allowance: number }
|
|
161
|
+
>();
|
|
126
162
|
if (orderedNodes.length >= 3) {
|
|
127
163
|
const first = orderedNodes[0];
|
|
128
164
|
const W = ctx.space.maxGroup;
|
|
129
165
|
let middleBytes = 0; // Σ bytes of the answers BETWEEN first and m-th
|
|
130
166
|
for (let m = 1; m < orderedNodes.length; m++) {
|
|
131
|
-
const key = first.node + "," + orderedNodes[m].node;
|
|
132
|
-
if (links.has(key)) {
|
|
133
|
-
middleBytes += orderedNodes[m].bytes.length;
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
167
|
// The N-ary interior legitimately holds every intermediate answer
|
|
137
168
|
// plus one W-quantum of glue per joint — pass that allowance so the
|
|
138
|
-
// bridge's phrase-scale cap admits the whole learnt run.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
ctx,
|
|
146
|
-
first.bytes,
|
|
147
|
-
orderedNodes[m].bytes,
|
|
148
|
-
allowance,
|
|
149
|
-
);
|
|
150
|
-
if (interior !== null) links.set(key, interior);
|
|
169
|
+
// bridge's phrase-scale cap admits the whole learnt run. Asked only
|
|
170
|
+
// when the pairwise bridge of the same key (if offered) found nothing.
|
|
171
|
+
nary.set(first.node + "," + orderedNodes[m].node, {
|
|
172
|
+
left: first.bytes,
|
|
173
|
+
right: orderedNodes[m].bytes,
|
|
174
|
+
allowance: middleBytes + (m + 1) * W,
|
|
175
|
+
});
|
|
151
176
|
middleBytes += orderedNodes[m].bytes.length;
|
|
152
177
|
}
|
|
153
178
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
179
|
+
const granted = new Map<string, Uint8Array | null>();
|
|
180
|
+
return {
|
|
181
|
+
offered: new Set([...pairwise, ...nary.keys()]),
|
|
182
|
+
granted,
|
|
183
|
+
asked: new Set(),
|
|
184
|
+
async grant(keys) {
|
|
185
|
+
const found: Array<[string, Uint8Array]> = [];
|
|
186
|
+
for (const key of keys) {
|
|
187
|
+
if (granted.has(key)) continue;
|
|
188
|
+
let link: Uint8Array | null = null;
|
|
189
|
+
if (pairwise.has(key)) {
|
|
190
|
+
const comma = key.indexOf(",");
|
|
191
|
+
if (ctx.meter) ctx.meter.coverBridges++;
|
|
192
|
+
link = await bridge(
|
|
193
|
+
ctx,
|
|
194
|
+
read(ctx, Number(key.slice(0, comma))),
|
|
195
|
+
read(ctx, Number(key.slice(comma + 1))),
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
const whole = nary.get(key);
|
|
199
|
+
if (link === null && whole !== undefined) {
|
|
200
|
+
if (ctx.meter) {
|
|
201
|
+
ctx.meter.coverBridges++;
|
|
202
|
+
ctx.meter.coverAllowanceBytes += whole.allowance;
|
|
203
|
+
}
|
|
204
|
+
link = await bridge(ctx, whole.left, whole.right, whole.allowance);
|
|
205
|
+
}
|
|
206
|
+
granted.set(key, link);
|
|
207
|
+
if (link !== null) found.push([key, link]);
|
|
208
|
+
}
|
|
209
|
+
if (found.length > 0) {
|
|
210
|
+
ctx.trace?.step(
|
|
211
|
+
"resolveConnectors",
|
|
212
|
+
ordered.map((s) => rItem(read(ctx, s.payload), "answer", s.payload)),
|
|
213
|
+
found.map(([pair, bytes]) => ({
|
|
214
|
+
text: `${pair}: "${decodeText(bytes)}"`,
|
|
215
|
+
role: "connector",
|
|
216
|
+
} as RationaleItem)),
|
|
217
|
+
"the bytes the graph splices between adjacent answers the search reached (asked of the gist space)",
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
};
|
|
166
222
|
}
|
|
167
223
|
|
|
168
224
|
// ── Pipeline mechanism ──────────────────────────────────────────────────────
|
|
@@ -178,7 +234,7 @@ export const coverMechanism: PipelineMechanism = {
|
|
|
178
234
|
|
|
179
235
|
// Masking: computed spans are authoritative. Remove recognised sites
|
|
180
236
|
// that overlap any computed span before building the cover search.
|
|
181
|
-
|
|
237
|
+
let sites = computed.length === 0
|
|
182
238
|
? rec.sites
|
|
183
239
|
: rec.sites.filter((s) =>
|
|
184
240
|
!computed.some((u) => s.start < u.j && u.i < s.end)
|
|
@@ -203,14 +259,53 @@ export const coverMechanism: PipelineMechanism = {
|
|
|
203
259
|
);
|
|
204
260
|
}
|
|
205
261
|
|
|
262
|
+
// A FRAGMENT ANSWERS OTHER QUESTIONS. A recognised form that sits inside
|
|
263
|
+
// other forms (it has structural parents or containers) holds continuations
|
|
264
|
+
// because the forms it is a piece of were asked — suffix inheritance gives
|
|
265
|
+
// `f death` the answer of every `… place of death` question. Choosing one of
|
|
266
|
+
// several such continuations by popularity voices some other question's
|
|
267
|
+
// answer, and the cover used to account the fragment's bytes as explained by
|
|
268
|
+
// it. A fragment with several continuations leads somewhere FOR THIS
|
|
269
|
+
// QUESTION only when the question names one (traverse.ts, the exact tier).
|
|
270
|
+
// A form that is (nearly) the whole question is not a piece of it: the
|
|
271
|
+
// question says nothing beyond it, so its continuations answer THIS question.
|
|
272
|
+
const asked = ctx._edgeAsked;
|
|
273
|
+
const W0 = ctx.space.maxGroup;
|
|
274
|
+
const leading = asked === null
|
|
275
|
+
? sites
|
|
276
|
+
: sites.filter((s) =>
|
|
277
|
+
query.length - (s.end - s.start) < W0 ||
|
|
278
|
+
!(ctx.store.hasParents(s.payload) ||
|
|
279
|
+
ctx.store.hasContainers(s.payload)) ||
|
|
280
|
+
ctx.store.nextFirst(s.payload, 2).length < 2 ||
|
|
281
|
+
namedContinuations(ctx, s.payload, asked) !== null
|
|
282
|
+
);
|
|
283
|
+
if (leading.length < sites.length) {
|
|
284
|
+
if (ctx.meter) {
|
|
285
|
+
ctx.meter.unaskedFragments += sites.length - leading.length;
|
|
286
|
+
}
|
|
287
|
+
ctx.trace?.step(
|
|
288
|
+
"unaskedFragments",
|
|
289
|
+
sites.filter((s) => !leading.includes(s)).map((s) =>
|
|
290
|
+
rItem(query.subarray(s.start, s.end), "fragment", s.payload, [
|
|
291
|
+
s.start,
|
|
292
|
+
s.end,
|
|
293
|
+
])
|
|
294
|
+
),
|
|
295
|
+
[],
|
|
296
|
+
"a piece of other forms whose continuations the question names none of — it answers other questions",
|
|
297
|
+
);
|
|
298
|
+
sites = leading;
|
|
299
|
+
}
|
|
300
|
+
|
|
206
301
|
if (sites.length === 0 && computed.length === 0) return [];
|
|
207
302
|
|
|
208
303
|
const connectors = ctx.meter
|
|
209
|
-
?
|
|
210
|
-
"cover.
|
|
211
|
-
() =>
|
|
304
|
+
? ctx.meter.timeSync(
|
|
305
|
+
"cover.offerConnectors",
|
|
306
|
+
() => offerConnectors(ctx, sites, query),
|
|
212
307
|
)
|
|
213
|
-
:
|
|
308
|
+
: offerConnectors(ctx, sites, query);
|
|
214
309
|
let splits = rec.splits;
|
|
215
310
|
if (computed.length > 0) {
|
|
216
311
|
splits = new Set(rec.splits);
|
|
@@ -220,17 +315,15 @@ export const coverMechanism: PipelineMechanism = {
|
|
|
220
315
|
}
|
|
221
316
|
}
|
|
222
317
|
const concepts = ctx.meter
|
|
223
|
-
?
|
|
224
|
-
"cover.
|
|
225
|
-
() =>
|
|
318
|
+
? ctx.meter.timeSync(
|
|
319
|
+
"cover.offerConcepts",
|
|
320
|
+
() => offerConcepts(ctx, sites),
|
|
226
321
|
)
|
|
227
|
-
:
|
|
322
|
+
: offerConcepts(ctx, sites);
|
|
228
323
|
|
|
229
324
|
const coverDeps = [
|
|
230
325
|
ctx.trace?.lastIndex("recognise"),
|
|
231
326
|
ctx.trace?.lastIndex("computeExtensions"),
|
|
232
|
-
ctx.trace?.lastIndex("resolveConcepts"),
|
|
233
|
-
ctx.trace?.lastIndex("resolveConnectors"),
|
|
234
327
|
].filter((x): x is number => x !== undefined);
|
|
235
328
|
|
|
236
329
|
// Convert ComputedSpan[] to ComputedResult[] for the graph search.
|
|
@@ -251,17 +344,33 @@ export const coverMechanism: PipelineMechanism = {
|
|
|
251
344
|
...computedResults.map((u) => rItem(u.bytes, "computed")),
|
|
252
345
|
], coverDeps.length ? coverDeps : undefined);
|
|
253
346
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
347
|
+
// COVER, GRANT WHAT IT ASKED, COVER AGAIN — until a cover asks for nothing
|
|
348
|
+
// (see Licence in graph-search.ts). Only the final cover's derivations reach the
|
|
349
|
+
// rationale; a provisional one is superseded, not part of the answer.
|
|
350
|
+
let derivations: DerivationStep[][] = [];
|
|
351
|
+
let solved: ReturnType<typeof ctx.search.cover>;
|
|
352
|
+
for (;;) {
|
|
353
|
+
derivations = [];
|
|
354
|
+
solved = ctx.search.cover(
|
|
355
|
+
query.length,
|
|
356
|
+
sites,
|
|
357
|
+
concepts,
|
|
358
|
+
rec.leaves,
|
|
359
|
+
splits,
|
|
360
|
+
undefined,
|
|
361
|
+
connectors,
|
|
362
|
+
computedResults,
|
|
363
|
+
ctx.trace ? (steps) => derivations.push(steps) : undefined,
|
|
364
|
+
);
|
|
365
|
+
if (concepts.asked.size === 0 && connectors.asked.size === 0) break;
|
|
366
|
+
const grant = async () => {
|
|
367
|
+
await concepts.grant([...concepts.asked]);
|
|
368
|
+
await connectors.grant([...connectors.asked]);
|
|
369
|
+
};
|
|
370
|
+
if (ctx.meter) await ctx.meter.time("cover.grant", grant);
|
|
371
|
+
else await grant();
|
|
372
|
+
}
|
|
373
|
+
for (const steps of derivations) traceDerivation(ctx, steps);
|
|
265
374
|
const segs = solved && solved.segs;
|
|
266
375
|
tCover?.done(
|
|
267
376
|
segs === null
|
|
@@ -317,8 +426,19 @@ export const coverMechanism: PipelineMechanism = {
|
|
|
317
426
|
// restated span contributes nothing to the composed answer, so it must
|
|
318
427
|
// not be priced as if it did (PASS-carried bytes are priced already;
|
|
319
428
|
// the diagnostic label reflects the same distinction).
|
|
429
|
+
//
|
|
430
|
+
// …and a span made of nothing but corpus-global scaffolding names nothing:
|
|
431
|
+
// every window of it is a piece of more than √N stored forms, so the form
|
|
432
|
+
// recognised there — the song `What`, in the trained store — is one of
|
|
433
|
+
// thousands it could be. Voicing that form's fact explains no byte the
|
|
434
|
+
// asker owes: measured, `What country is Jerry Bock a citizen of?` was won
|
|
435
|
+
// by `The performer of What is Melinda Marx.` glued onto the right fact.
|
|
436
|
+
const scaffold = scaffoldSpans(ctx, query);
|
|
320
437
|
const accounted: Array<[number, number]> = segs
|
|
321
|
-
.filter((s) =>
|
|
438
|
+
.filter((s) =>
|
|
439
|
+
s.rec && !segRestatesQuery(s, query, query.length, W) &&
|
|
440
|
+
!scaffold.some(([a, b]) => a <= s.i && s.j <= b)
|
|
441
|
+
)
|
|
322
442
|
.map((s) => [s.i, s.j]);
|
|
323
443
|
|
|
324
444
|
return [{
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
// that contains it.
|
|
9
9
|
|
|
10
10
|
import type { MindContext } from "../types.js";
|
|
11
|
-
import {
|
|
12
|
-
import { follow, isSpanShaped, locate, skillExemplar } from "../match.js";
|
|
11
|
+
import { locate } from "../match.js";
|
|
13
12
|
import { concatBytes, indexOf } from "../../bytes.js";
|
|
14
13
|
import { decodeText } from "../rationale.js";
|
|
15
14
|
import type {
|
|
@@ -103,7 +103,7 @@ import { bytesEqual } from "../../bytes.js";
|
|
|
103
103
|
import { rItem } from "../trace.js";
|
|
104
104
|
import { formsOpenedBy } from "../traverse.js";
|
|
105
105
|
import { STEP } from "../graph-search.js";
|
|
106
|
-
import type { PipelineMechanism
|
|
106
|
+
import type { PipelineMechanism } from "../pipeline-mechanism.js";
|
|
107
107
|
|
|
108
108
|
/** A trained form the query opens, and the bytes by which it continues. */
|
|
109
109
|
export interface PrefixCompletion {
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
import { cosine } from "../../vec.js";
|
|
8
8
|
import {
|
|
9
|
-
conceptThreshold,
|
|
10
9
|
consensusFloor,
|
|
11
10
|
dominates,
|
|
12
11
|
identityBar,
|
|
@@ -15,8 +14,14 @@ import {
|
|
|
15
14
|
} from "../../geometry.js";
|
|
16
15
|
import type { MindContext } from "../types.js";
|
|
17
16
|
import { gistOf, read, resolve } from "../primitives.js";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
17
|
+
import { indexOf } from "../../bytes.js";
|
|
18
|
+
import {
|
|
19
|
+
allWindowsAreScaffolding,
|
|
20
|
+
askedEvidence,
|
|
21
|
+
corpusN,
|
|
22
|
+
guidedFirst,
|
|
23
|
+
hubBound,
|
|
24
|
+
} from "../traverse.js";
|
|
20
25
|
import {
|
|
21
26
|
follow,
|
|
22
27
|
project,
|
|
@@ -73,7 +78,6 @@ export async function recallByResonance(
|
|
|
73
78
|
...(complete ? { complete } : {}),
|
|
74
79
|
};
|
|
75
80
|
};
|
|
76
|
-
const k = pre.k;
|
|
77
81
|
const queryGist = pre.guide;
|
|
78
82
|
|
|
79
83
|
// 0. Exact self-match — content-addressed, deterministic.
|
|
@@ -156,10 +160,18 @@ export async function recallByResonance(
|
|
|
156
160
|
g !== null && g.length > 0 &&
|
|
157
161
|
!lawRestates(query, g, 0, { proper: true })
|
|
158
162
|
) {
|
|
163
|
+
// EVIDENCE TRAVELS: when the question NAMED the continuation followed
|
|
164
|
+
// (traverse.ts, the exact tier — `Who is the father of Frederick II?`
|
|
165
|
+
// witnesses the father fact's own question `Frederick II father`), the
|
|
166
|
+
// spans that named it are explained too, not only the argument.
|
|
167
|
+
const hop = guidedFirst(ctx, arg.payload);
|
|
168
|
+
const named = hop === undefined
|
|
169
|
+
? []
|
|
170
|
+
: askedEvidence(ctx, arg.payload, hop);
|
|
159
171
|
return ground(
|
|
160
172
|
g,
|
|
161
173
|
"argument binding — the query's sole edge-source constituent, continuation followed",
|
|
162
|
-
[[arg.start, arg.end]],
|
|
174
|
+
[[arg.start, arg.end], ...named],
|
|
163
175
|
STEP,
|
|
164
176
|
);
|
|
165
177
|
}
|
|
@@ -38,7 +38,7 @@ import type { MindContext } from "../types.js";
|
|
|
38
38
|
import type { FrameInstance } from "../match.js";
|
|
39
39
|
import { carriesFillers, distinct, follow, substituteAll } from "../match.js";
|
|
40
40
|
import { dominates } from "../../geometry.js";
|
|
41
|
-
import { bytesEqual
|
|
41
|
+
import { bytesEqual } from "../../bytes.js";
|
|
42
42
|
import { restates } from "../derivation.js";
|
|
43
43
|
import { STEP } from "../graph-search.js";
|
|
44
44
|
import type {
|
package/src/mind/mind.ts
CHANGED
|
@@ -9,41 +9,20 @@
|
|
|
9
9
|
// Architecture: 4 primitives × 2 patterns = all inference.
|
|
10
10
|
// Implementation split across src/mind/*.ts — this file assembles the Mind class.
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { makeKeyring, rng, setVecConfig, Vec } from "../vec.js";
|
|
13
|
+
import { Sema, Space } from "../sema.js";
|
|
14
14
|
import { sampleCorpus, searchCorpus } from "./corpus.js";
|
|
15
15
|
import type { CorpusPair, CorpusResult } from "./corpus.js";
|
|
16
16
|
import { Alphabet } from "../alphabet.js";
|
|
17
|
-
import {
|
|
18
|
-
bytesToTree,
|
|
19
|
-
contentFoldIncremental,
|
|
20
|
-
Grid,
|
|
21
|
-
gridToTree,
|
|
22
|
-
hilbertBytes,
|
|
23
|
-
reachThreshold,
|
|
24
|
-
stackGrids,
|
|
25
|
-
} from "../geometry.js";
|
|
17
|
+
import { contentFoldIncremental, Grid, reachThreshold } from "../geometry.js";
|
|
26
18
|
import { keyEnds } from "./canonical.js";
|
|
27
19
|
import type { ContentFold } from "../geometry.js";
|
|
28
20
|
import { BoundedMap, type Store } from "../store.js";
|
|
29
21
|
import { SQliteStore } from "../store-sqlite.js";
|
|
30
22
|
import { type MindConfig, resolveConfig } from "../config.js";
|
|
31
23
|
import { type Canon, canonHash, textCanon, textEdgeTrim } from "../canon.js";
|
|
32
|
-
import {
|
|
33
|
-
|
|
34
|
-
coverSequence,
|
|
35
|
-
lightestDerivation,
|
|
36
|
-
} from "../derive/src/index.js";
|
|
37
|
-
import { bytesEqual, concat2, concatBytes, indexOf } from "../bytes.js";
|
|
38
|
-
import {
|
|
39
|
-
type ComputedResult,
|
|
40
|
-
type DerivationItem,
|
|
41
|
-
type DerivationStep,
|
|
42
|
-
GraphSearch,
|
|
43
|
-
type Leaf,
|
|
44
|
-
type Seg,
|
|
45
|
-
type Site,
|
|
46
|
-
} from "./graph-search.js";
|
|
24
|
+
import { bytesEqual, concat2 } from "../bytes.js";
|
|
25
|
+
import { GraphSearch, type Leaf, type Site } from "./graph-search.js";
|
|
47
26
|
import { Alu } from "../alu/src/index.js";
|
|
48
27
|
import type { ComputedSpan, ExtensionHost } from "../extension.js";
|
|
49
28
|
|
|
@@ -147,16 +126,12 @@ interface ConversationData {
|
|
|
147
126
|
|
|
148
127
|
// Mind module imports
|
|
149
128
|
import type { AttentionRead, MindContext, Recognition } from "./types.js";
|
|
150
|
-
import { changedNodes, liftAnswer, spliceAll } from "./types.js";
|
|
151
129
|
import {
|
|
152
130
|
canonResolve as canonResolveImpl,
|
|
153
|
-
foldTree,
|
|
154
131
|
gistOf,
|
|
155
132
|
inputBytes,
|
|
156
|
-
latin1Key,
|
|
157
133
|
perceive as perceiveImpl,
|
|
158
134
|
perceiveKey,
|
|
159
|
-
read,
|
|
160
135
|
resolve as resolveImpl,
|
|
161
136
|
} from "./primitives.js";
|
|
162
137
|
import {
|
|
@@ -166,6 +141,7 @@ import {
|
|
|
166
141
|
leadsSomewhere,
|
|
167
142
|
} from "./traverse.js";
|
|
168
143
|
import { invalidateJunctionCache } from "./junction.js";
|
|
144
|
+
import type { WindowIndex } from "./evidence.js";
|
|
169
145
|
import { follow } from "./match.js";
|
|
170
146
|
import { recognise, segment } from "./recognition.js";
|
|
171
147
|
import { meaningOf } from "./resonance.js";
|
|
@@ -358,6 +334,8 @@ export class Mind implements MindContext {
|
|
|
358
334
|
* first-edge behaviour) and the reverse projection uses it for
|
|
359
335
|
* reverse-recall disambiguation via `chooseAmong`. */
|
|
360
336
|
_edgeGuide: Vec | null = null;
|
|
337
|
+
/** See {@link MindContext._edgeAsked}. */
|
|
338
|
+
_edgeAsked: { bytes: Uint8Array; index: WindowIndex } | null = null;
|
|
361
339
|
/** Per-response memo of {@link chooseNext} picks — ensures every mechanism
|
|
362
340
|
* of a single response follows the SAME continuation for each ambiguous
|
|
363
341
|
* context node. */
|
|
@@ -672,6 +650,7 @@ export class Mind implements MindContext {
|
|
|
672
650
|
this.canon = null;
|
|
673
651
|
this.canonMemo = null;
|
|
674
652
|
this._edgeGuide = null;
|
|
653
|
+
this._edgeAsked = null;
|
|
675
654
|
this._edgeChoice.clear();
|
|
676
655
|
}
|
|
677
656
|
|