@hviana/sema 0.2.2 → 0.2.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.
- package/dist/src/mind/articulation.js +1 -1
- package/dist/src/mind/attention.d.ts +18 -2
- package/dist/src/mind/attention.js +88 -18
- package/dist/src/mind/bridge.d.ts +30 -0
- package/dist/src/mind/bridge.js +569 -0
- package/dist/src/mind/graph-search.d.ts +16 -1
- package/dist/src/mind/graph-search.js +34 -5
- package/dist/src/mind/match.d.ts +15 -2
- package/dist/src/mind/match.js +3 -8
- package/dist/src/mind/mechanisms/alu.js +8 -1
- package/dist/src/mind/mechanisms/cast.d.ts +54 -0
- package/dist/src/mind/mechanisms/cast.js +303 -48
- package/dist/src/mind/mechanisms/cover.js +24 -32
- package/dist/src/mind/mechanisms/extraction.js +75 -30
- package/dist/src/mind/mechanisms/recall.js +66 -0
- package/dist/src/mind/mind.d.ts +1 -0
- package/dist/src/mind/mind.js +6 -1
- package/dist/src/mind/pipeline.js +34 -2
- package/dist/src/mind/reasoning.d.ts +20 -1
- package/dist/src/mind/reasoning.js +84 -6
- package/dist/src/mind/recognition.js +157 -13
- package/dist/src/mind/traverse.js +16 -0
- package/dist/src/mind/types.d.ts +65 -2
- package/dist/src/mind/types.js +53 -7
- package/dist/src/store.d.ts +12 -3
- package/dist/src/store.js +9 -3
- package/package.json +1 -1
- package/src/mind/articulation.ts +1 -0
- package/src/mind/attention.ts +105 -17
- package/src/mind/bridge.ts +596 -0
- package/src/mind/graph-search.ts +59 -2
- package/src/mind/match.ts +19 -5
- package/src/mind/mechanisms/alu.ts +8 -1
- package/src/mind/mechanisms/cast.ts +336 -46
- package/src/mind/mechanisms/cover.ts +31 -36
- package/src/mind/mechanisms/extraction.ts +101 -40
- package/src/mind/mechanisms/recall.ts +79 -0
- package/src/mind/mind.ts +7 -1
- package/src/mind/pipeline.ts +37 -2
- package/src/mind/reasoning.ts +97 -5
- package/src/mind/recognition.ts +160 -12
- package/src/mind/traverse.ts +17 -0
- package/src/mind/types.ts +110 -6
- package/src/store.ts +19 -5
- package/test/35-attention-confidence.test.mjs +139 -0
- package/test/36-already-answered-fusion.test.mjs +128 -0
- package/test/37-cluster-dispersion-fusion.test.mjs +190 -0
- package/test/38-reason-restate-guard.test.mjs +94 -0
- package/test/39-cast-restate-guard.test.mjs +102 -0
- package/test/40-choosenext-scale-guard.test.mjs +75 -0
- package/test/41-seatofnode-direction.test.mjs +85 -0
- package/test/42-recognise-trace-idempotence.test.mjs +106 -0
- package/test/43-cast-analog-seat.test.mjs +244 -0
- package/test/44-recognise-edge-whitespace.test.mjs +63 -0
- package/test/45-liftanswer-restated-trim.test.mjs +60 -0
- package/test/46-recognise-multibyte-edge.test.mjs +85 -0
- package/test/47-cast-comparison-coverage.test.mjs +134 -0
- package/test/48-recognise-turn-connective.test.mjs +125 -0
- package/test/49-natural-units-synonym-bridge.test.mjs +175 -0
- package/test/50-cast-analog-consensus-floor.test.mjs +179 -0
|
@@ -63,6 +63,7 @@ function readCover(derivation) {
|
|
|
63
63
|
bytes: out.bytes,
|
|
64
64
|
rec: out.rec,
|
|
65
65
|
node: out.node,
|
|
66
|
+
computed: out.computed,
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
node = node.premises[0];
|
|
@@ -205,7 +206,7 @@ export class GraphSearch {
|
|
|
205
206
|
* Any learnt connector between two rewrites is spliced IN by the in-search
|
|
206
207
|
* connector rule (see {@link outRules}), so the returned spans already carry
|
|
207
208
|
* it — there is no post-pass. */
|
|
208
|
-
cover(queryLen, sites, conceptTarget, leaves, splits, substitutions, connectors, computedResults,
|
|
209
|
+
cover(queryLen, sites, conceptTarget, leaves, splits, starts, substitutions, connectors, computedResults,
|
|
209
210
|
/** When given, receives the lightest derivation's rule applications — the
|
|
210
211
|
* full adapted A*LD proof tree as classified {@link DerivationStep}s — for the TOP
|
|
211
212
|
* cover only (a recursive recompletion solves its own sub-cover and is not
|
|
@@ -221,6 +222,7 @@ export class GraphSearch {
|
|
|
221
222
|
sites,
|
|
222
223
|
leaves,
|
|
223
224
|
splits,
|
|
225
|
+
starts,
|
|
224
226
|
}, conceptTarget, substitutions, connectors, computedResults, onDerivation);
|
|
225
227
|
}
|
|
226
228
|
/** Build the deduction system for one span and return its lightest cover's
|
|
@@ -237,7 +239,7 @@ export class GraphSearch {
|
|
|
237
239
|
* decomposes, two recomposes, any mix — and stops only when it reaches a node
|
|
238
240
|
* that leads nowhere new, never at an arbitrary count. */
|
|
239
241
|
solve(spanLen, recognition, conceptTarget, substitutions, connectors, computedResults, onDerivation) {
|
|
240
|
-
const system = this.buildSearch(spanLen, recognition.sites, conceptTarget, recognition.leaves, recognition.splits, substitutions, connectors, computedResults);
|
|
242
|
+
const system = this.buildSearch(spanLen, recognition.sites, conceptTarget, recognition.leaves, recognition.splits, recognition.starts, substitutions, connectors, computedResults);
|
|
241
243
|
const derivation = lightestDerivation(system);
|
|
242
244
|
// When covering under a substitution map (articulation), a form→out rule is
|
|
243
245
|
// the form EMITTING the asker's voice, not grounding to its own answer — so
|
|
@@ -257,8 +259,15 @@ export class GraphSearch {
|
|
|
257
259
|
* adjacent fragments toward a known leaf (findLeaf) or branch (findBranch);
|
|
258
260
|
* a completion fused with its neighbour may spell a deeper learned form the
|
|
259
261
|
* flat probes can't name, recovered canonically by {@link resolve}. */
|
|
260
|
-
buildSearch(queryLen, sites, conceptTarget, leaves, splits, substitutions, connectors, computedResults) {
|
|
262
|
+
buildSearch(queryLen, sites, conceptTarget, leaves, splits, starts, substitutions, connectors, computedResults) {
|
|
261
263
|
const W = this.maxGroup; // fusible span ceiling (shortest composite bound)
|
|
264
|
+
// Same corpus-scale hub floor {@link atomIsHub}/{@link atomReach} (traverse.ts)
|
|
265
|
+
// derive for byte atoms — duplicated here rather than imported because this
|
|
266
|
+
// module is deliberately host-based (no MindContext), and both inputs
|
|
267
|
+
// (maxGroup, edgeSourceCount) are already in scope with no ctx needed. If
|
|
268
|
+
// the formula ever changes, it must change in BOTH places (see canonical.ts's
|
|
269
|
+
// header for the same write/read-side duplication convention).
|
|
270
|
+
const atomsAreHubs = Math.max(1, Math.ceil((this.store.edgeSourceCount() * W) / 256)) > Math.ceil(Math.sqrt(Math.max(2, this.store.edgeSourceCount())));
|
|
262
271
|
const nodeBytes = (n) => this.store.bytesPrefix(n, ALL);
|
|
263
272
|
// Content-addressed probes over the store's hash-cons maps — the same keys
|
|
264
273
|
// training filled. No byte-by-byte trie walk.
|
|
@@ -350,6 +359,7 @@ export class GraphSearch {
|
|
|
350
359
|
cover: true,
|
|
351
360
|
rec: true,
|
|
352
361
|
node: u.node,
|
|
362
|
+
computed: true,
|
|
353
363
|
},
|
|
354
364
|
cost: STEP,
|
|
355
365
|
};
|
|
@@ -388,6 +398,8 @@ export class GraphSearch {
|
|
|
388
398
|
return this.outRules(it, {
|
|
389
399
|
W,
|
|
390
400
|
splits,
|
|
401
|
+
starts,
|
|
402
|
+
atomsAreHubs,
|
|
391
403
|
coversDone,
|
|
392
404
|
outsByStart,
|
|
393
405
|
outsByEnd,
|
|
@@ -845,7 +857,23 @@ export class GraphSearch {
|
|
|
845
857
|
* enters the graph as a form the moment it names a node. */
|
|
846
858
|
*fuse(l, r, ctx) {
|
|
847
859
|
const bytes = concat2(l.bytes, r.bytes);
|
|
848
|
-
|
|
860
|
+
// A PURE leaf-leaf fuse (neither side already a recognised completion)
|
|
861
|
+
// is opportunistic cross-leaf recovery exactly like recognition.ts's own
|
|
862
|
+
// canonical chain — findLeaf/findBranch here have no idea WHY these two
|
|
863
|
+
// leaves are adjacent, only that their concatenation happens to spell a
|
|
864
|
+
// trained form ("hi" recovered from "W[hi]ch"). The same corpus-scale
|
|
865
|
+
// caution recognition.ts's `boundary` gate applies: trust it fully when
|
|
866
|
+
// `l.i` is a position the query's OWN fold chose as a boundary (real
|
|
867
|
+
// structural evidence); past the scale where atoms themselves stop
|
|
868
|
+
// discriminating, an interior offset's opportunistic match is noise, not
|
|
869
|
+
// a genuine cross-leaf recovery. A completion-involved fuse (l.rec ||
|
|
870
|
+
// r.rec) is a different, legitimate case — a rewrite growing into its
|
|
871
|
+
// neighbour — and is exempt, same as recognition.ts's rec-derived sites.
|
|
872
|
+
const trusted = l.rec || r.rec || ctx.starts.has(l.i) ||
|
|
873
|
+
!ctx.atomsAreHubs;
|
|
874
|
+
let node = (trusted && bytes.length <= ctx.W)
|
|
875
|
+
? ctx.findLeafU(bytes)
|
|
876
|
+
: undefined;
|
|
849
877
|
// Whether this pair ACTUALLY forms a 2-child branch — the hard evidence
|
|
850
878
|
// that the fused bytes are a learned form worth keeping alive. Derived
|
|
851
879
|
// from the same findBranchU probe that sets `node`; when false, the pair
|
|
@@ -853,7 +881,8 @@ export class GraphSearch {
|
|
|
853
881
|
// node cannot contribute to any further fusion (findBranch needs two
|
|
854
882
|
// nodes, resolve needs a completion, and findLeaf already had its chance).
|
|
855
883
|
let pairFormsBranch = false;
|
|
856
|
-
if (node === undefined && l.node !== undefined &&
|
|
884
|
+
if (trusted && node === undefined && l.node !== undefined &&
|
|
885
|
+
r.node !== undefined) {
|
|
857
886
|
node = ctx.findBranchU([l.node, r.node]);
|
|
858
887
|
pairFormsBranch = node !== undefined;
|
|
859
888
|
}
|
package/dist/src/mind/match.d.ts
CHANGED
|
@@ -64,8 +64,21 @@ export declare function haloSiblings(ctx: MindContext, id: number, halo?: Vec |
|
|
|
64
64
|
* strength, not a pick. Returns the direct halo cosine, or failing that the
|
|
65
65
|
* highest mutual-halo-sibling min-score (second-order analogy), or failing
|
|
66
66
|
* that the SHARED-FRAME strength (below) — the gate CAST's comparison
|
|
67
|
-
* schema validates genuine analogs with (bar: significanceBar).
|
|
68
|
-
|
|
67
|
+
* schema validates genuine analogs with (bar: significanceBar).
|
|
68
|
+
*
|
|
69
|
+
* The result names its TIER alongside the score: `halo: true` means the
|
|
70
|
+
* score cleared a significanceBar-gated HALO tier (direct company cosine
|
|
71
|
+
* or mutual-sibling) — genuine distributional evidence; `halo: false`
|
|
72
|
+
* means only the structural shared-frame fallback matched, a coverage
|
|
73
|
+
* fraction with no bar of its own. CAST's comparison gate treats the two
|
|
74
|
+
* differently (see cast.ts): halo evidence stands alone, frame evidence
|
|
75
|
+
* needs the query to have named the analog or the climb root to be
|
|
76
|
+
* trusted. */
|
|
77
|
+
export interface AnalogyEvidence {
|
|
78
|
+
score: number;
|
|
79
|
+
halo: boolean;
|
|
80
|
+
}
|
|
81
|
+
export declare function analogyStrength(ctx: MindContext, a: number, b: number): Promise<AnalogyEvidence>;
|
|
69
82
|
/** The STRUCTURAL analogy tier: two nodes are analogs when their byte
|
|
70
83
|
* streams share a LEARNT frame — a content-addressed flat form of at least
|
|
71
84
|
* one full river window (W bytes, the perception quantum) that occurs in
|
package/dist/src/mind/match.js
CHANGED
|
@@ -257,11 +257,6 @@ export async function haloSiblings(ctx, id, halo, bar = conceptThreshold(ctx.sto
|
|
|
257
257
|
memo.set(id, out);
|
|
258
258
|
return out;
|
|
259
259
|
}
|
|
260
|
-
/** The DISTRIBUTIONAL matcher between two nodes: mutual-nearest-neighbour
|
|
261
|
-
* strength, not a pick. Returns the direct halo cosine, or failing that the
|
|
262
|
-
* highest mutual-halo-sibling min-score (second-order analogy), or failing
|
|
263
|
-
* that the SHARED-FRAME strength (below) — the gate CAST's comparison
|
|
264
|
-
* schema validates genuine analogs with (bar: significanceBar). */
|
|
265
260
|
export async function analogyStrength(ctx, a, b) {
|
|
266
261
|
const ha = ctx.store.halo(a);
|
|
267
262
|
const hb = ctx.store.halo(b);
|
|
@@ -269,7 +264,7 @@ export async function analogyStrength(ctx, a, b) {
|
|
|
269
264
|
const bar = significanceBar(ctx.store.D);
|
|
270
265
|
const direct = cosine(ha, hb);
|
|
271
266
|
if (direct >= bar)
|
|
272
|
-
return direct;
|
|
267
|
+
return { score: direct, halo: true };
|
|
273
268
|
const sibsA = await haloSiblings(ctx, a, ha, bar);
|
|
274
269
|
const sibsB = await haloSiblings(ctx, b, hb, bar);
|
|
275
270
|
let best = 0;
|
|
@@ -282,9 +277,9 @@ export async function analogyStrength(ctx, a, b) {
|
|
|
282
277
|
}
|
|
283
278
|
}
|
|
284
279
|
if (best > 0)
|
|
285
|
-
return best;
|
|
280
|
+
return { score: best, halo: true };
|
|
286
281
|
}
|
|
287
|
-
return sharedFrameStrength(ctx, a, b);
|
|
282
|
+
return { score: sharedFrameStrength(ctx, a, b), halo: false };
|
|
288
283
|
}
|
|
289
284
|
/** The STRUCTURAL analogy tier: two nodes are analogs when their byte
|
|
290
285
|
* streams share a LEARNT frame — a content-addressed flat form of at least
|
|
@@ -12,7 +12,14 @@ import { unexplainedLabel } from "../rationale.js";
|
|
|
12
12
|
export function aluToMechanism(alu) {
|
|
13
13
|
return {
|
|
14
14
|
name: "alu",
|
|
15
|
-
|
|
15
|
+
// Not a cover derivation: cover.ts composes an answer by walking
|
|
16
|
+
// recognised query STRUCTURE; the ALU evaluates a recognised expression
|
|
17
|
+
// to its authoritative result and hands the bytes back untouched. It
|
|
18
|
+
// shares cover's near-zero floor (computation always wins, masked into
|
|
19
|
+
// cover's own search — see mechanisms/cover.ts), but the candidate this
|
|
20
|
+
// produces is not one of cover's derivations, so it carries its own
|
|
21
|
+
// honest label, the same way extract/cast/recall each carry theirs.
|
|
22
|
+
provenance: "alu",
|
|
16
23
|
parse: (query) => alu.parse(query),
|
|
17
24
|
async floor(_ctx, _query, pre, _worthRunning) {
|
|
18
25
|
return pre.computed.length > 0 ? 0 : null;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MindContext } from "../types.js";
|
|
2
|
+
import type { Vec } from "../../vec.js";
|
|
2
3
|
/** A CAST answer plus its elementary evidence for think's grounding decider:
|
|
3
4
|
* `accounted` — the query spans the weave's aligned runs explain; `moves` —
|
|
4
5
|
* the ladder cost of the acts the taken branch performed (STEP per
|
|
@@ -13,6 +14,59 @@ export interface CastResult {
|
|
|
13
14
|
* Task 2 note in pipeline.ts's Candidate interface). */
|
|
14
15
|
unexplained: string;
|
|
15
16
|
}
|
|
17
|
+
/** The seat that establishes a node's role in an analogical comparison:
|
|
18
|
+
* the REVERSE context (what leads to it) when a predecessor genuinely
|
|
19
|
+
* ESTABLISHES id — introduces or describes it by name — else the FORWARD
|
|
20
|
+
* continuation (what it leads to), else `fallback`.
|
|
21
|
+
*
|
|
22
|
+
* An earlier version gated this purely on `prevCount(id) > 0`: any
|
|
23
|
+
* predecessor at all was treated as proof of a genuine named ENTITY
|
|
24
|
+
* (seat it by what established it), while no predecessor meant a bare
|
|
25
|
+
* learnt CONTEXT (seat it by what it leads to, since voicing it verbatim
|
|
26
|
+
* would answer a question with a question). That test measured the wrong
|
|
27
|
+
* thing — a broad sample of this store's own question-shaped nodes showed
|
|
28
|
+
* the large majority (≈71%) have at least one predecessor, most of them a
|
|
29
|
+
* handful of generic, high-fan-out sentences that recur as an INCIDENTAL
|
|
30
|
+
* neighbour to dozens of otherwise-unrelated destinations (a SmolSent-
|
|
31
|
+
* style sentence-adjacency artifact, never naming or describing what
|
|
32
|
+
* follows). Traced live: "What is the capital of France?" — whose own
|
|
33
|
+
* forward edge unambiguously resolves to "The capital of France is
|
|
34
|
+
* Paris." — has exactly one such incidental predecessor ("Create an
|
|
35
|
+
* example of a types of questions a GPT model can answer.?"), wrongly
|
|
36
|
+
* read as disqualifying proof of "genuine entity."
|
|
37
|
+
*
|
|
38
|
+
* A plain forward-first swap (matching {@link project}'s universal
|
|
39
|
+
* priority) over-corrected: test/29's C2/C3 pin that a genuine entity
|
|
40
|
+
* analog (e.g. "Leonardo da Vinci", established by "The Mona Lisa was
|
|
41
|
+
* painted by Leonardo da Vinci.") must be seated by that establishing
|
|
42
|
+
* sentence, NOT by its own biography fact — voicing the bio leaks exactly
|
|
43
|
+
* what a comparison must keep out, and loses the embedded "Mona Lisa"
|
|
44
|
+
* term C3 relies on for a further hop.
|
|
45
|
+
*
|
|
46
|
+
* The distinguishing signal is content-addressed, not a count: a genuine
|
|
47
|
+
* establishing predecessor's bytes CONTAIN id's own bytes — it names or
|
|
48
|
+
* describes id ("...painted by Leonardo da Vinci." contains "Leonardo da
|
|
49
|
+
* Vinci"). An incidental adjacency predecessor never does — it merely
|
|
50
|
+
* preceded id in some unrelated document without ever mentioning it. No
|
|
51
|
+
* new tuned constant: containment is the same primitive `restatesQuery`
|
|
52
|
+
* and `dominates`-style checks already use throughout this codebase.
|
|
53
|
+
*
|
|
54
|
+
* `allowForward` (default true) gates the FORWARD branch specifically —
|
|
55
|
+
* see the call sites below: the DOMINANT is what the query is actually
|
|
56
|
+
* ASKING, so completing it forward is the whole point; an ANALOG is only
|
|
57
|
+
* being CITED for comparison; the query never asked about IT, so chasing
|
|
58
|
+
* its own further continuation drifts onto whatever coincidentally
|
|
59
|
+
* follows it in the corpus. Traced live: the analog "What is the capital
|
|
60
|
+
* of Japan?\nTokyo is the capital of Japan." is ALREADY a complete,
|
|
61
|
+
* self-answering unit (prevCount 0, so no establishing predecessor
|
|
62
|
+
* either) — its sole forward edge is "And what is the capital of the
|
|
63
|
+
* Moon?", an unrelated quiz question sharing nothing but corpus
|
|
64
|
+
* adjacency. With forward disallowed, an analog like this falls through
|
|
65
|
+
* to `fallback` — its own bytes, exactly the complete fact that made it a
|
|
66
|
+
* genuine analog in the first place. See
|
|
67
|
+
* test/41-seatofnode-direction.test.mjs and
|
|
68
|
+
* test/43-cast-analog-seat.test.mjs. */
|
|
69
|
+
export declare function seatOfNode(ctx: MindContext, id: number, guide: Vec | null | undefined, fallback: Uint8Array, allowForward?: boolean): Promise<Uint8Array>;
|
|
16
70
|
/** CAST's own entry gates, checked once here and reused by
|
|
17
71
|
/** The main CAST entry point. Given a query and its pre-computed pre.rec.sites,
|
|
18
72
|
* determine whether the query weaves together multiple independent learnt
|