@hviana/sema 0.9.0 → 0.9.1
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 +20 -0
- package/dist/src/meter.js +21 -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/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 +101 -58
- package/dist/src/mind/mechanisms/recall.js +0 -1
- package/dist/src/mind/mind.js +2 -2
- package/dist/src/mind/pipeline.d.ts +5 -1
- package/dist/src/mind/pipeline.js +175 -87
- 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 +445 -321
- package/dist/src/mind/recognition.js +29 -13
- package/dist/src/mind/resonance.js +1 -11
- package/dist/src/mind/traverse.d.ts +3 -3
- package/dist/src/mind/traverse.js +3 -3
- package/dist/src/mind/types.d.ts +7 -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 +18 -18
- package/docs/INVARIANTS.md +16 -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/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 +21 -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/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 +149 -84
- package/src/mind/mechanisms/extraction.ts +1 -2
- package/src/mind/mechanisms/prefix-completion.ts +1 -1
- package/src/mind/mechanisms/recall.ts +1 -3
- package/src/mind/mechanisms/reference.ts +1 -1
- package/src/mind/mind.ts +5 -30
- package/src/mind/pipeline.ts +206 -102
- package/src/mind/primitives.ts +119 -43
- package/src/mind/reasoning.ts +558 -413
- 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 +3 -3
- package/src/mind/types.ts +9 -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/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/pipeline.ts
CHANGED
|
@@ -14,9 +14,10 @@ import { PASS, STEP } from "./graph-search.js";
|
|
|
14
14
|
import type { ComputedSpan } from "../extension.js";
|
|
15
15
|
import { gistOf, read, resolve } from "./primitives.js";
|
|
16
16
|
import { recognise } from "./recognition.js";
|
|
17
|
-
import {
|
|
17
|
+
import { fusionLayer, walkLayer } from "./reasoning.js";
|
|
18
18
|
import {
|
|
19
19
|
closed,
|
|
20
|
+
closeOver,
|
|
20
21
|
type DerivationState,
|
|
21
22
|
remainderOf,
|
|
22
23
|
type Span,
|
|
@@ -27,7 +28,11 @@ import {
|
|
|
27
28
|
import { rItem } from "./trace.js";
|
|
28
29
|
import { unexplainedLabel } from "./rationale.js";
|
|
29
30
|
import { hubBound } from "./traverse.js";
|
|
30
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
type MechanismResult,
|
|
33
|
+
type PipelineMechanism,
|
|
34
|
+
Precomputed,
|
|
35
|
+
} from "./pipeline-mechanism.js";
|
|
31
36
|
import { coverMechanism } from "./mechanisms/cover.js";
|
|
32
37
|
import { castMechanism } from "./mechanisms/cast.js";
|
|
33
38
|
import { confluenceMechanism } from "./mechanisms/confluence.js";
|
|
@@ -38,7 +43,7 @@ import { recallMechanism } from "./mechanisms/recall.js";
|
|
|
38
43
|
|
|
39
44
|
// Re-exports: cover's pre-resolution helpers and the ALU adapter kept
|
|
40
45
|
// importable from the pipeline module (their historical home).
|
|
41
|
-
export {
|
|
46
|
+
export { offerConcepts, offerConnectors } from "./mechanisms/cover.js";
|
|
42
47
|
export { aluToMechanism } from "./mechanisms/alu.js";
|
|
43
48
|
|
|
44
49
|
// ── Extension dispatch (pre-loop parse) ─────────────────────────────────────
|
|
@@ -161,6 +166,10 @@ export interface RegimePredictionData {
|
|
|
161
166
|
* CAST's floor) — the bar the incumbent must sit at or below for the
|
|
162
167
|
* consensus climb to be skipped. */
|
|
163
168
|
climbFloorGrade: number;
|
|
169
|
+
/** The lowest grade reached by a mechanism run AHEAD of a dearer one (see
|
|
170
|
+
* the grounding loop), when one ran and grounded: a bound below
|
|
171
|
+
* `climbFloorGrade` makes the regime retrieval whatever the incumbent. */
|
|
172
|
+
boundGrade?: number;
|
|
164
173
|
}
|
|
165
174
|
|
|
166
175
|
/** Think: a single lightest-derivation exploration of the Sema graph.
|
|
@@ -335,7 +344,7 @@ export async function think(
|
|
|
335
344
|
// below.
|
|
336
345
|
const incumbent = best as Candidate | null;
|
|
337
346
|
const incumbentGrade = incumbent === null ? null : grade(incumbent.weight);
|
|
338
|
-
const regime: "retrieval" | "composition" =
|
|
347
|
+
const regime: "retrieval" | "composition" = worthDeclared(2 * STEP)
|
|
339
348
|
? "composition"
|
|
340
349
|
: "retrieval";
|
|
341
350
|
ctx.trace?.step(
|
|
@@ -343,8 +352,10 @@ export async function think(
|
|
|
343
352
|
[rItem(query, "query")],
|
|
344
353
|
[],
|
|
345
354
|
regime === "retrieval"
|
|
346
|
-
?
|
|
347
|
-
`
|
|
355
|
+
? (incumbentGrade !== null && incumbentGrade <= climbFloorGrade
|
|
356
|
+
? `retrieval regime — incumbent grade ${incumbentGrade} ≤ climb floor ${climbFloorGrade}, `
|
|
357
|
+
: `retrieval regime — grade ${bound} already reached by a mechanism run ahead, below climb floor ${climbFloorGrade}, `) +
|
|
358
|
+
`so no mechanism floored above that grade runs; CAST will not climb`
|
|
348
359
|
: `composition regime — ${
|
|
349
360
|
incumbentGrade === null
|
|
350
361
|
? "no incumbent (nothing grounded)"
|
|
@@ -356,6 +367,7 @@ export async function think(
|
|
|
356
367
|
regime,
|
|
357
368
|
incumbentGrade,
|
|
358
369
|
climbFloorGrade,
|
|
370
|
+
...(bound !== Infinity ? { boundGrade: bound } : {}),
|
|
359
371
|
} satisfies RegimePredictionData,
|
|
360
372
|
);
|
|
361
373
|
};
|
|
@@ -363,19 +375,139 @@ export async function think(
|
|
|
363
375
|
// Per-mechanism accounting (src/meter.ts). The market's whole premise is
|
|
364
376
|
// that mechanisms compete on one cost scale — so the profiling read-out is
|
|
365
377
|
// also per-mechanism, uniformly: the loop never asks which one it holds.
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
378
|
+
//
|
|
379
|
+
// A CHEAPER BOUND IS LOOKED AT BEFORE A DEARER ONE IS PAID FOR.
|
|
380
|
+
//
|
|
381
|
+
// The declared order is the tie-break priority, and the pruning above is
|
|
382
|
+
// only as strong as the incumbent it has: a mechanism floored LOWER than the
|
|
383
|
+
// one about to invest, but declared after it, could not prune it. Measured
|
|
384
|
+
// on the 31.7M-node store: a lowercased dialogue turn (#97 of the battery)
|
|
385
|
+
// was won by recall at grade 1 — after CAST (floor grade 2) had paid the
|
|
386
|
+
// consensus climb and the weave, confluence (3) a reach climb, and extraction
|
|
387
|
+
// and reference their reads: ~10 s of a 12.6 s response, for candidates that
|
|
388
|
+
// could not win.
|
|
389
|
+
//
|
|
390
|
+
// So before mechanism `m` first-touches anything, every LATER mechanism whose
|
|
391
|
+
// bound is strictly lower runs AHEAD of it, cheapest bound first, and the
|
|
392
|
+
// lowest grade any of them reaches becomes `bound`. A mechanism whose floor
|
|
393
|
+
// grade exceeds `bound` is then skipped. THE DECISION IS UNCHANGED — the
|
|
394
|
+
// same candidate wins as in the declared order:
|
|
395
|
+
// • a mechanism `p` run ahead with best grade g bounds the final grade by
|
|
396
|
+
// g: in the declared order p either runs (its candidate is weighed) or is
|
|
397
|
+
// pruned by an incumbent already at or below p's floor ≤ g;
|
|
398
|
+
// • so a mechanism floored above `bound` has only candidates the final
|
|
399
|
+
// winner strictly outgrades — and with every candidate above `bound`
|
|
400
|
+
// dropped, every mechanism floored at or below it meets the same
|
|
401
|
+
// run-or-prune decision (`f < incumbent` iff `f < min(incumbent,
|
|
402
|
+
// bound + 1)` for f ≤ bound) and yields the same candidates;
|
|
403
|
+
// • and the winner is chosen from the candidates at or below `bound`, in
|
|
404
|
+
// declared order — `consider` replays them where they are declared.
|
|
405
|
+
// Equal-grade floors are NOT skipped (≤, not <): a mechanism declared earlier
|
|
406
|
+
// keeps the tie it would have won. Running `p` ahead is never extra work:
|
|
407
|
+
// what prunes p in the declared order is a candidate at or below p's floor,
|
|
408
|
+
// which only a mechanism floored at or below it can produce — and every such
|
|
409
|
+
// mechanism is either already run or run ahead of p.
|
|
410
|
+
//
|
|
411
|
+
// The bound is learnt by asking `floor` with a `worthRunning` that refuses:
|
|
412
|
+
// under the investment discipline (pipeline-mechanism.ts) a floor that cannot
|
|
413
|
+
// pay returns its bound UNINVESTED, so the question costs no analysis.
|
|
414
|
+
const refuse = () => false;
|
|
415
|
+
const probed: Array<number | null | undefined> = new Array(
|
|
416
|
+
mechanisms.length,
|
|
417
|
+
);
|
|
418
|
+
const probeGrade = async (i: number): Promise<number | null> => {
|
|
419
|
+
if (probed[i] === undefined) {
|
|
420
|
+
const f = await mechanisms[i].floor(ctx, query, pre, refuse);
|
|
421
|
+
probed[i] = f === null ? null : grade(f);
|
|
422
|
+
}
|
|
423
|
+
return probed[i]!;
|
|
424
|
+
};
|
|
425
|
+
/** Per mechanism: its floor once computed, and its results once run. */
|
|
426
|
+
const floors = new Map<number, number | null>();
|
|
427
|
+
const runs = new Map<number, MechanismResult[]>();
|
|
428
|
+
let bound = Infinity;
|
|
429
|
+
const worthAhead = (floor: number) =>
|
|
430
|
+
grade(floor) <
|
|
431
|
+
Math.min(best === null ? Infinity : grade(best.weight), bound);
|
|
432
|
+
const worthDeclared = (floor: number) =>
|
|
433
|
+
worthRunning(floor) && grade(floor) <= bound;
|
|
434
|
+
const floorOf = async (
|
|
435
|
+
i: number,
|
|
436
|
+
worth: (floor: number) => boolean,
|
|
437
|
+
): Promise<number | null> => {
|
|
438
|
+
if (floors.has(i)) return floors.get(i)!;
|
|
439
|
+
const mech = mechanisms[i];
|
|
369
440
|
const floor = meter
|
|
370
441
|
? await meter.time(
|
|
371
442
|
`${mech.name}.floor`,
|
|
372
|
-
() => mech.floor(ctx, query, pre,
|
|
443
|
+
() => mech.floor(ctx, query, pre, worth),
|
|
373
444
|
)
|
|
374
|
-
: await mech.floor(ctx, query, pre,
|
|
445
|
+
: await mech.floor(ctx, query, pre, worth);
|
|
375
446
|
if (meter) {
|
|
376
447
|
if (floor === null) meter.mechanismSkips++;
|
|
377
448
|
else meter.mechanismFloors++;
|
|
378
449
|
}
|
|
450
|
+
floors.set(i, floor);
|
|
451
|
+
return floor;
|
|
452
|
+
};
|
|
453
|
+
const runOf = async (i: number): Promise<MechanismResult[]> => {
|
|
454
|
+
let results = runs.get(i);
|
|
455
|
+
if (results === undefined) {
|
|
456
|
+
const mech = mechanisms[i];
|
|
457
|
+
if (meter) meter.mechanismRuns++;
|
|
458
|
+
results = meter
|
|
459
|
+
? await meter.time(`${mech.name}.run`, () => mech.run(ctx, query, pre))
|
|
460
|
+
: await mech.run(ctx, query, pre);
|
|
461
|
+
runs.set(i, results);
|
|
462
|
+
}
|
|
463
|
+
return results;
|
|
464
|
+
};
|
|
465
|
+
const runAhead = async (mi: number) => {
|
|
466
|
+
const g = await probeGrade(mi);
|
|
467
|
+
if (g === null) return;
|
|
468
|
+
const ahead: Array<[number, number]> = [];
|
|
469
|
+
for (let j = mi + 1; j < mechanisms.length; j++) {
|
|
470
|
+
if (floors.has(j)) continue;
|
|
471
|
+
const gj = await probeGrade(j);
|
|
472
|
+
if (gj !== null && gj < g) ahead.push([gj, j]);
|
|
473
|
+
}
|
|
474
|
+
ahead.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
|
475
|
+
for (const [gj, j] of ahead) {
|
|
476
|
+
// Only what the declared order would also run: a bound that cannot beat
|
|
477
|
+
// what is already held is not even asked for its real floor.
|
|
478
|
+
if (
|
|
479
|
+
!(gj < Math.min(best === null ? Infinity : grade(best.weight), bound))
|
|
480
|
+
) {
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
const floor = await floorOf(j, worthAhead);
|
|
484
|
+
if (floor === null || !worthAhead(floor)) continue;
|
|
485
|
+
ctx.trace?.step(
|
|
486
|
+
"runAhead",
|
|
487
|
+
[],
|
|
488
|
+
[],
|
|
489
|
+
`${mechanisms[j].name} runs ahead of ${
|
|
490
|
+
mechanisms[mi].name
|
|
491
|
+
} — its floor (grade ${grade(floor)}) is below ${
|
|
492
|
+
mechanisms[mi].name
|
|
493
|
+
}'s (grade ${g}), so its result bounds what ${
|
|
494
|
+
mechanisms[mi].name
|
|
495
|
+
} could win`,
|
|
496
|
+
);
|
|
497
|
+
for (const r of await runOf(j)) {
|
|
498
|
+
// `consider` drops an empty answer, so it bounds nothing.
|
|
499
|
+
if (r.bytes.length === 0) continue;
|
|
500
|
+
bound = Math.min(bound, grade(weigh(r.accounted, r.moves)));
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
for (let mi = 0; mi < mechanisms.length; mi++) {
|
|
505
|
+
const mech = mechanisms[mi];
|
|
506
|
+
if (mi > 0) {
|
|
507
|
+
await runAhead(mi);
|
|
508
|
+
reportRegime();
|
|
509
|
+
}
|
|
510
|
+
const floor = await floorOf(mi, worthDeclared);
|
|
379
511
|
if (floor === null) {
|
|
380
512
|
ctx.trace?.step(
|
|
381
513
|
"skipMechanism",
|
|
@@ -385,6 +517,16 @@ export async function think(
|
|
|
385
517
|
);
|
|
386
518
|
continue;
|
|
387
519
|
}
|
|
520
|
+
if (grade(floor) > bound) {
|
|
521
|
+
if (meter) meter.mechanismsBounded++;
|
|
522
|
+
ctx.trace?.step(
|
|
523
|
+
"skipMechanism",
|
|
524
|
+
[],
|
|
525
|
+
[],
|
|
526
|
+
`${mech.name} skipped — floor ${floor} cannot beat grade ${bound}, already reached by a mechanism run ahead`,
|
|
527
|
+
);
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
388
530
|
if (!worthRunning(floor)) {
|
|
389
531
|
ctx.trace?.step(
|
|
390
532
|
"skipMechanism",
|
|
@@ -396,10 +538,7 @@ export async function think(
|
|
|
396
538
|
);
|
|
397
539
|
continue;
|
|
398
540
|
}
|
|
399
|
-
|
|
400
|
-
const results = meter
|
|
401
|
-
? await meter.time(`${mech.name}.run`, () => mech.run(ctx, query, pre))
|
|
402
|
-
: await mech.run(ctx, query, pre);
|
|
541
|
+
const results = await runOf(mi);
|
|
403
542
|
for (const r of results) {
|
|
404
543
|
// ONE FORMULA, EVERY CANDIDATE: the chart's derivation reports how many
|
|
405
544
|
// discrete moves it made and which bytes it could not recognise; the
|
|
@@ -544,25 +683,20 @@ export async function think(
|
|
|
544
683
|
// without evidence stays owed, and a later transition pays it only by carrying
|
|
545
684
|
// it (the law reads the window; see derivation.ts). Same reading, one
|
|
546
685
|
// definition — not a second spelling of it here.
|
|
547
|
-
const
|
|
686
|
+
const priced: Array<[number, number]> = [
|
|
548
687
|
...decided.accounted,
|
|
549
688
|
...pre.computed.map((u): [number, number] => [u.i, u.j]),
|
|
550
|
-
]
|
|
689
|
+
];
|
|
690
|
+
const explained = priced.filter(([a, b]) =>
|
|
551
691
|
windowOf([a, b], answer, query, ctx.space.maxGroup) !== null
|
|
552
692
|
);
|
|
693
|
+
const paid = remainderOf(query.length, explained, ctx.space.maxGroup);
|
|
553
694
|
// WHAT THE CONSTRUCTION WITHHOLDS, at or above one quantum: the difference between
|
|
554
695
|
// the remainder paid in full and the remainder paid by carrying. Both readings
|
|
555
|
-
// are the law's, so the floor is applied once and in one place
|
|
556
|
-
|
|
557
|
-
query.length,
|
|
558
|
-
[
|
|
559
|
-
...decided.accounted,
|
|
560
|
-
...pre.computed.map((u): [number, number] => [u.i, u.j]),
|
|
561
|
-
],
|
|
562
|
-
ctx.space.maxGroup,
|
|
563
|
-
);
|
|
564
|
-
const paid = remainderOf(query.length, explained, ctx.space.maxGroup);
|
|
696
|
+
// are the law's, so the floor is applied once and in one place — and the
|
|
697
|
+
// paid-in-full reading is computed only when a meter will read it.
|
|
565
698
|
if (ctx.meter) {
|
|
699
|
+
const paidInFull = remainderOf(query.length, priced, ctx.space.maxGroup);
|
|
566
700
|
ctx.meter.groundingWithheldBytes += unaccountedBytes(paid) -
|
|
567
701
|
unaccountedBytes(paidInFull);
|
|
568
702
|
}
|
|
@@ -664,89 +798,59 @@ export async function think(
|
|
|
664
798
|
meter.postGroundingRemainderSpans += uncovered.length;
|
|
665
799
|
meter.postGroundingRemainderBytes += unaccountedBytes(uncovered);
|
|
666
800
|
}
|
|
667
|
-
// THE
|
|
668
|
-
// real questions that stopped with no note anywhere. They never reached the
|
|
669
|
-
// offer: `decided.complete` says the grounding supplied a fixed point, so the
|
|
670
|
-
// walk is skipped BY DESIGN and the state is the grounding's own. That state
|
|
671
|
-
// carries `fixed: true` (the trace already reports it), and the law's first
|
|
672
|
-
// clause refuses any continuation against it — so there is no `null` here to
|
|
673
|
-
// read as exhaustion, and the `Offer` contract is not in play at all. The
|
|
674
|
-
// silent stop is therefore a NAMED state, not a gap.
|
|
801
|
+
// ── THE CLOSURE ENGINE ───────────────────────────────────────────────
|
|
675
802
|
//
|
|
676
|
-
//
|
|
677
|
-
//
|
|
678
|
-
//
|
|
679
|
-
//
|
|
680
|
-
//
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
//
|
|
690
|
-
//
|
|
691
|
-
//
|
|
692
|
-
//
|
|
693
|
-
//
|
|
694
|
-
//
|
|
695
|
-
//
|
|
696
|
-
//
|
|
697
|
-
//
|
|
698
|
-
//
|
|
699
|
-
//
|
|
700
|
-
//
|
|
701
|
-
//
|
|
702
|
-
// observed: a single space between two fully-computed arithmetic spans
|
|
703
|
-
// ("2+2 3+3") registered as "unaccounted" and pulled in an unrelated
|
|
704
|
-
// corpus fact, corrupting "4 6" into "4 63".
|
|
705
|
-
// THE GATE ASKS THE LAW, and that is an OPTIMISATION, not a tidy-up: the state
|
|
706
|
-
// above ALREADY carries the remainder (`remainderOf`, per-span, with the W
|
|
707
|
-
// floor applied), so asking it costs nothing, while the total this line used to
|
|
708
|
-
// compute (`unaccounted(explained)`) was one more sum over the spans on every
|
|
709
|
-
// response. The two readings are the same condition, not two: the ACCOUNTING
|
|
710
|
-
// applies the same W floor the gate does, so a gap below one quantum never
|
|
711
|
-
// survives into `explained` and the total cannot reach W without some single
|
|
712
|
-
// gap reaching it. Measured over twelve constructions at W = 4 (test/136.3,
|
|
713
|
-
// which pins the equivalence and both sides of it).
|
|
714
|
-
// Whether the winning candidate's entire recognised substance is
|
|
715
|
-
// COMPUTED — every accounted span exactly a pre.computed span, nothing
|
|
716
|
-
// from a genuinely recognised/climbed site. fuseAttention's lone-root
|
|
717
|
-
// shortcut assumes a single point of attention already IS primary's own
|
|
718
|
-
// source; that assumption is exactly backwards for a pure computation
|
|
719
|
-
// (an ALU result has no anchor of its own) — see fuseAttention's
|
|
720
|
-
// `unclimbed` parameter, gated there by Attention.breadth so a
|
|
721
|
-
// coincidental echo (which this flag alone cannot distinguish) is still
|
|
722
|
-
// rejected.
|
|
803
|
+
// The grounding's state is CLOSED under the law by two layers, in order: the
|
|
804
|
+
// multi-hop WALK (`walkLayer`: a forward absorb or a pivot, offered one at a
|
|
805
|
+
// time) and the multi-topic FUSION (`fusionLayer`: one composed transition).
|
|
806
|
+
// Every step either layer offers goes through the same `closure` and the same
|
|
807
|
+
// law; this function no longer sequences them or gates them by hand.
|
|
808
|
+
//
|
|
809
|
+
// WHAT USED TO BE TWO HAND-WRITTEN GATES IS NOW THE LAW'S, OR THE LAYER'S:
|
|
810
|
+
// • a declared-complete grounding (`fixed`) admits no transition — the
|
|
811
|
+
// engine enters no layer for it (the law's first clause), which is the
|
|
812
|
+
// walk-skip and the fusion-skip this branch used to spell separately;
|
|
813
|
+
// • a CLOSED derivation has nothing left for a second topic to account for,
|
|
814
|
+
// so the fusion layer does not ENGAGE — read off the state the walk
|
|
815
|
+
// reached, the one fusion is actually offered against.
|
|
816
|
+
//
|
|
817
|
+
// What the fusion needs from the grounding — whether its substance is purely
|
|
818
|
+
// computed (`unclimbed`) and where it stands in the query (`primarySpans`) —
|
|
819
|
+
// is the grounding's own evidence, resolved here where both readings are in
|
|
820
|
+
// hand.
|
|
821
|
+
//
|
|
822
|
+
// Whether the winning candidate's entire recognised substance is COMPUTED —
|
|
823
|
+
// every accounted span exactly a pre.computed span, nothing from a genuinely
|
|
824
|
+
// recognised/climbed site. fuseAttention's lone-root shortcut assumes a
|
|
825
|
+
// single point of attention already IS primary's own source; that assumption
|
|
826
|
+
// is exactly backwards for a pure computation (an ALU result has no anchor of
|
|
827
|
+
// its own) — gated there by Attention.breadth so a coincidental echo (which
|
|
828
|
+
// this flag alone cannot distinguish) is still rejected.
|
|
723
829
|
const unclimbed = state.accounted.length > 0 &&
|
|
724
830
|
state.accounted.every(([i, j]) =>
|
|
725
831
|
pre.computed.some((u) => u.i === i && u.j === j)
|
|
726
832
|
);
|
|
727
|
-
// Where the winning grounding stands in the query — fusion places primary
|
|
728
|
-
//
|
|
729
|
-
//
|
|
730
|
-
//
|
|
731
|
-
//
|
|
732
|
-
// read here for POSITION instead of for coverage — and resolved here, where
|
|
733
|
-
// both readings are in hand, rather than inside fuseAttention.
|
|
833
|
+
// Where the winning grounding stands in the query — fusion places primary by
|
|
834
|
+
// it. `accounted` is the cost-ladder read and is authoritative when
|
|
835
|
+
// non-empty; when it is empty the grounding is a pure COMPUTATION, whose
|
|
836
|
+
// evidence is its computed span — the cost-ladder-vs-coverage distinction
|
|
837
|
+
// `explained` above draws, read here for POSITION instead of coverage.
|
|
734
838
|
const primarySpans: ReadonlyArray<Span> = state.accounted.length > 0
|
|
735
839
|
? state.accounted
|
|
736
840
|
: pre.computed.map((u): [number, number] => [u.i, u.j]);
|
|
737
|
-
const fused =
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
841
|
+
const fused = await closeOver(
|
|
842
|
+
state,
|
|
843
|
+
query,
|
|
844
|
+
ctx.space.maxGroup,
|
|
845
|
+
[
|
|
846
|
+
walkLayer(ctx, query, preConsumed, pre, voiced),
|
|
847
|
+
{
|
|
848
|
+
...fusionLayer(ctx, query, pre, unclimbed, primarySpans),
|
|
849
|
+
engages: (d: DerivationState) => !closed(d),
|
|
850
|
+
},
|
|
851
|
+
],
|
|
852
|
+
meter ? (name, walk) => meter.time(name, walk) : undefined,
|
|
853
|
+
);
|
|
750
854
|
|
|
751
855
|
done(
|
|
752
856
|
fused.product,
|