@hviana/sema 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/example/demo.js +25 -25
  2. package/dist/example/train_base.d.ts +21 -19
  3. package/dist/example/train_base.js +1952 -1684
  4. package/dist/src/alphabet.d.ts +3 -3
  5. package/dist/src/alphabet.js +27 -24
  6. package/dist/src/alu/src/alu.d.ts +194 -169
  7. package/dist/src/alu/src/alu.js +414 -374
  8. package/dist/src/alu/src/expr.d.ts +43 -36
  9. package/dist/src/alu/src/expr.js +278 -252
  10. package/dist/src/alu/src/index.d.ts +98 -9
  11. package/dist/src/alu/src/index.js +63 -9
  12. package/dist/src/alu/src/kernel-arith.d.ts +5 -1
  13. package/dist/src/alu/src/kernel-arith.js +285 -195
  14. package/dist/src/alu/src/kernel-bits.d.ts +5 -1
  15. package/dist/src/alu/src/kernel-bits.js +115 -81
  16. package/dist/src/alu/src/kernel-logic.js +63 -33
  17. package/dist/src/alu/src/kernel-nd.js +195 -155
  18. package/dist/src/alu/src/kernel-numeric.d.ts +80 -16
  19. package/dist/src/alu/src/kernel-numeric.js +331 -259
  20. package/dist/src/alu/src/operation.d.ts +132 -112
  21. package/dist/src/alu/src/operation.js +163 -149
  22. package/dist/src/alu/src/parser.d.ts +175 -168
  23. package/dist/src/alu/src/parser.js +421 -382
  24. package/dist/src/alu/src/resonance.d.ts +25 -16
  25. package/dist/src/alu/src/resonance.js +56 -49
  26. package/dist/src/alu/src/text.d.ts +7 -3
  27. package/dist/src/alu/src/text.js +37 -31
  28. package/dist/src/alu/src/value.d.ts +14 -14
  29. package/dist/src/alu/src/value.js +160 -150
  30. package/dist/src/alu/test/alu.test.js +656 -543
  31. package/dist/src/bytes.d.ts +5 -1
  32. package/dist/src/bytes.js +40 -33
  33. package/dist/src/config.d.ts +102 -102
  34. package/dist/src/config.js +83 -83
  35. package/dist/src/derive/src/deduction.d.ts +62 -60
  36. package/dist/src/derive/src/deduction.js +109 -103
  37. package/dist/src/derive/src/index.d.ts +7 -1
  38. package/dist/src/derive/src/priority-queue.d.ts +8 -8
  39. package/dist/src/derive/src/priority-queue.js +61 -57
  40. package/dist/src/derive/src/rewrite.d.ts +18 -15
  41. package/dist/src/derive/src/rewrite.js +67 -59
  42. package/dist/src/derive/src/trie.d.ts +56 -56
  43. package/dist/src/derive/src/trie.js +179 -175
  44. package/dist/src/derive/test/derive.test.js +100 -96
  45. package/dist/src/extension.d.ts +16 -13
  46. package/dist/src/geometry.d.ts +42 -17
  47. package/dist/src/geometry.js +266 -235
  48. package/dist/src/index.d.ts +17 -2
  49. package/dist/src/index.js +7 -1
  50. package/dist/src/ingest-cache.d.ts +30 -25
  51. package/dist/src/ingest-cache.js +127 -108
  52. package/dist/src/mind/articulation.d.ts +5 -1
  53. package/dist/src/mind/articulation.js +112 -77
  54. package/dist/src/mind/attention.d.ts +108 -40
  55. package/dist/src/mind/attention.js +871 -749
  56. package/dist/src/mind/canonical.d.ts +19 -4
  57. package/dist/src/mind/canonical.js +31 -27
  58. package/dist/src/mind/graph-search.d.ts +225 -201
  59. package/dist/src/mind/graph-search.js +821 -742
  60. package/dist/src/mind/index.d.ts +10 -2
  61. package/dist/src/mind/junction.d.ts +58 -31
  62. package/dist/src/mind/junction.js +237 -172
  63. package/dist/src/mind/learning.d.ts +52 -16
  64. package/dist/src/mind/learning.js +165 -143
  65. package/dist/src/mind/match.d.ts +69 -20
  66. package/dist/src/mind/match.js +318 -259
  67. package/dist/src/mind/mechanisms/alu.js +16 -16
  68. package/dist/src/mind/mechanisms/cast.d.ts +13 -9
  69. package/dist/src/mind/mechanisms/cast.js +456 -363
  70. package/dist/src/mind/mechanisms/confluence.d.ts +12 -8
  71. package/dist/src/mind/mechanisms/confluence.js +183 -152
  72. package/dist/src/mind/mechanisms/cover.d.ts +8 -2
  73. package/dist/src/mind/mechanisms/cover.js +210 -148
  74. package/dist/src/mind/mechanisms/extraction.d.ts +34 -8
  75. package/dist/src/mind/mechanisms/extraction.js +288 -234
  76. package/dist/src/mind/mechanisms/recall.d.ts +10 -6
  77. package/dist/src/mind/mechanisms/recall.js +185 -126
  78. package/dist/src/mind/mind.d.ts +154 -129
  79. package/dist/src/mind/mind.js +288 -258
  80. package/dist/src/mind/pipeline-mechanism.d.ts +124 -112
  81. package/dist/src/mind/pipeline-mechanism.js +172 -161
  82. package/dist/src/mind/pipeline.d.ts +14 -4
  83. package/dist/src/mind/pipeline.js +189 -125
  84. package/dist/src/mind/primitives.d.ts +32 -8
  85. package/dist/src/mind/primitives.js +117 -99
  86. package/dist/src/mind/rationale.d.ts +98 -86
  87. package/dist/src/mind/rationale.js +121 -113
  88. package/dist/src/mind/reasoning.d.ts +13 -2
  89. package/dist/src/mind/reasoning.js +166 -129
  90. package/dist/src/mind/recognition.d.ts +4 -1
  91. package/dist/src/mind/recognition.js +208 -183
  92. package/dist/src/mind/resonance.d.ts +22 -5
  93. package/dist/src/mind/resonance.js +0 -0
  94. package/dist/src/mind/trace.d.ts +25 -6
  95. package/dist/src/mind/trace.js +58 -50
  96. package/dist/src/mind/traverse.d.ts +58 -16
  97. package/dist/src/mind/traverse.js +357 -304
  98. package/dist/src/mind/types.d.ts +127 -120
  99. package/dist/src/mind/types.js +69 -60
  100. package/dist/src/rabitq-hnsw/src/database.d.ts +179 -177
  101. package/dist/src/rabitq-hnsw/src/database.js +359 -342
  102. package/dist/src/rabitq-hnsw/src/heap.d.ts +12 -12
  103. package/dist/src/rabitq-hnsw/src/heap.js +80 -75
  104. package/dist/src/rabitq-hnsw/src/hnsw.d.ts +103 -103
  105. package/dist/src/rabitq-hnsw/src/hnsw.js +454 -428
  106. package/dist/src/rabitq-hnsw/src/index.d.ts +6 -1
  107. package/dist/src/rabitq-hnsw/src/prng.d.ts +10 -10
  108. package/dist/src/rabitq-hnsw/src/prng.js +27 -25
  109. package/dist/src/rabitq-hnsw/src/rabitq.d.ts +69 -69
  110. package/dist/src/rabitq-hnsw/src/rabitq.js +262 -246
  111. package/dist/src/rabitq-hnsw/src/store.d.ts +132 -132
  112. package/dist/src/rabitq-hnsw/src/store.js +843 -752
  113. package/dist/src/rabitq-hnsw/test/hnsw.test.js +1054 -805
  114. package/dist/src/sema.d.ts +13 -9
  115. package/dist/src/sema.js +40 -26
  116. package/dist/src/store-sqlite.d.ts +166 -144
  117. package/dist/src/store-sqlite.js +660 -578
  118. package/dist/src/store.d.ts +630 -593
  119. package/dist/src/store.js +1581 -1440
  120. package/dist/src/vec.d.ts +9 -5
  121. package/dist/src/vec.js +73 -61
  122. package/package.json +2 -2
@@ -3,16 +3,16 @@ import type { GraphSearchHost } from "./types.js";
3
3
  /** A recognised form: a span of the query that names a node already in the
4
4
  * store. `payload` is that node id. */
5
5
  export interface Site {
6
- start: number;
7
- end: number;
8
- payload: number;
6
+ start: number;
7
+ end: number;
8
+ payload: number;
9
9
  }
10
10
  /** A perceived leaf of the query tree, carrying the node id it resolves to. */
11
11
  export interface Leaf {
12
- start: number;
13
- end: number;
14
- bytes: Uint8Array;
15
- node: number | null;
12
+ start: number;
13
+ end: number;
14
+ bytes: Uint8Array;
15
+ node: number | null;
16
16
  }
17
17
  /** A COMPUTED span: the result of applying a manual rule (an extension's
18
18
  * operation — e.g. the `alu` extension's arithmetic) to a recognised stretch
@@ -24,36 +24,36 @@ export interface Leaf {
24
24
  * happens to be computed rather than stored). `node` is the canonical id of
25
25
  * the result bytes when the store already holds them, else undefined. */
26
26
  export interface ComputedResult {
27
- i: number;
28
- j: number;
29
- bytes: Uint8Array;
30
- node?: number;
27
+ i: number;
28
+ j: number;
29
+ bytes: Uint8Array;
30
+ node?: number;
31
31
  }
32
32
  export type GItem = {
33
- kind: "cover";
34
- p: number;
33
+ kind: "cover";
34
+ p: number;
35
35
  } | {
36
- kind: "form";
37
- i: number;
38
- j: number;
39
- node: number;
40
- via: boolean;
41
- /** Set when this form was born by RECOMPOSING rewritten parts into a deeper
42
- * learned whole (the fuse of ≥2 recognised completions that names an
43
- * edge-bearing node). Its onward continuation is charged at MICRO, not
44
- * STEP: once parts are recomposed into a learned form, following that form
45
- * to its grounded answer is the recomposition completing — so the
46
- * consolidated, more-explanatory reading wins over leaving the parts split.
47
- * See {@link GraphSearch.fuse} and {@link GraphSearch.formRules}. */
48
- rcmp?: boolean;
36
+ kind: "form";
37
+ i: number;
38
+ j: number;
39
+ node: number;
40
+ via: boolean;
41
+ /** Set when this form was born by RECOMPOSING rewritten parts into a deeper
42
+ * learned whole (the fuse of ≥2 recognised completions that names an
43
+ * edge-bearing node). Its onward continuation is charged at MICRO, not
44
+ * STEP: once parts are recomposed into a learned form, following that form
45
+ * to its grounded answer is the recomposition completing — so the
46
+ * consolidated, more-explanatory reading wins over leaving the parts split.
47
+ * See {@link GraphSearch.fuse} and {@link GraphSearch.formRules}. */
48
+ rcmp?: boolean;
49
49
  } | {
50
- kind: "out";
51
- i: number;
52
- j: number;
53
- bytes: Uint8Array;
54
- cover: boolean;
55
- rec: boolean;
56
- node?: number;
50
+ kind: "out";
51
+ i: number;
52
+ j: number;
53
+ bytes: Uint8Array;
54
+ cover: boolean;
55
+ rec: boolean;
56
+ node?: number;
57
57
  };
58
58
  export declare const STEP = 1;
59
59
  export declare const CONCEPT = 10;
@@ -67,11 +67,11 @@ export declare const MICRO = 0.001;
67
67
  * span resolved to (when known) — for a recognised completion it is the chain's
68
68
  * terminal node, the foothold the bridge walks edges from. */
69
69
  export interface Seg {
70
- i: number;
71
- j: number;
72
- bytes: Uint8Array;
73
- rec: boolean;
74
- node?: number;
70
+ i: number;
71
+ j: number;
72
+ bytes: Uint8Array;
73
+ rec: boolean;
74
+ node?: number;
75
75
  }
76
76
  /** One rule application inside the cover's lightest derivation — the FINEST
77
77
  * grain of Sema's core reasoning, one node of the adapted A*LD proof tree. `move`
@@ -82,189 +82,213 @@ export interface Seg {
82
82
  * `order` is its post-order position so a tracer can replay the proof in the
83
83
  * order it was built (premises before conclusion). */
84
84
  export interface DerivationStep {
85
- order: number;
86
- move: DerivationMove;
87
- premises: DerivationItem[];
88
- conclusion: DerivationItem;
89
- cost: number;
90
- /** The `order`s of the steps that produced this one's premises — the EXACT
91
- * data-flow edges of the proof tree (a `bridge` names the `ground` whose
92
- * `out` it crossed and the earlier `cover` it extended). A premise that is
93
- * an axiom (a seed leaf/form/computed result, never a rule conclusion) has no
94
- * producer and contributes no edge, so this lists only the derived premises —
95
- * the finest dependency structure the inference holds. */
96
- producers: number[];
85
+ order: number;
86
+ move: DerivationMove;
87
+ premises: DerivationItem[];
88
+ conclusion: DerivationItem;
89
+ cost: number;
90
+ /** The `order`s of the steps that produced this one's premises — the EXACT
91
+ * data-flow edges of the proof tree (a `bridge` names the `ground` whose
92
+ * `out` it crossed and the earlier `cover` it extended). A premise that is
93
+ * an axiom (a seed leaf/form/computed result, never a rule conclusion) has no
94
+ * producer and contributes no edge, so this lists only the derived premises —
95
+ * the finest dependency structure the inference holds. */
96
+ producers: number[];
97
97
  }
98
98
  /** A premise or conclusion of a {@link DerivationStep}, flattened from a {@link
99
99
  * GItem} into the fields a rationale cares about. */
100
100
  export interface DerivationItem {
101
- kind: "cover" | "form" | "out";
102
- /** `[i, j)` span for a form/out; for a cover item, `[p, p]`. */
103
- span: [number, number];
104
- /** The bytes an `out` carries (the only item kind that holds output bytes). */
105
- bytes?: Uint8Array;
106
- /** The graph node a form/out resolves to, when known. */
107
- node?: number;
101
+ kind: "cover" | "form" | "out";
102
+ /** `[i, j)` span for a form/out; for a cover item, `[p, p]`. */
103
+ span: [number, number];
104
+ /** The bytes an `out` carries (the only item kind that holds output bytes). */
105
+ bytes?: Uint8Array;
106
+ /** The graph node a form/out resolves to, when known. */
107
+ node?: number;
108
108
  }
109
109
  /** The reasoning act a derivation rule performs — the human name for which of
110
110
  * {@link GraphSearch}'s rules fired, recovered from the rule's premise/
111
111
  * conclusion shape (the rules carry no label, so this classifies by structure,
112
112
  * the single place that maps rule geometry to a name). */
113
- export type DerivationMove = "axiom" | "follow-edge" | "concept-hop" | "voice" | "ground" | "splice-connector" | "split" | "fuse" | "recompose" | "bridge" | "pool-vote" | "step";
113
+ export type DerivationMove =
114
+ | "axiom"
115
+ | "follow-edge"
116
+ | "concept-hop"
117
+ | "voice"
118
+ | "ground"
119
+ | "splice-connector"
120
+ | "split"
121
+ | "fuse"
122
+ | "recompose"
123
+ | "bridge"
124
+ | "pool-vote"
125
+ | "step";
114
126
  /** The lightest-derivation search over the Sema graph. One instance binds the
115
127
  * store, `maxGroup` (the fusible span ceiling), and the canonical
116
128
  * {@link resolve} callback; {@link cover} then solves one query. */
117
129
  export declare class GraphSearch {
118
- private readonly store;
119
- private readonly maxGroup;
120
- /** The host whose capabilities the search consults: resolve (canonical node
121
- * id of a byte span), recogniseSpan (content-addressed graph lookup for
122
- * recursive completion), and chooseNext (distributional-evidence edge
123
- * disambiguation when a recognised form has multiple continuations). */
124
- private readonly host;
125
- constructor(store: Store, maxGroup: number,
130
+ private readonly store;
131
+ private readonly maxGroup;
132
+ /** The host whose capabilities the search consults: resolve (canonical node
133
+ * id of a byte span), recogniseSpan (content-addressed graph lookup for
134
+ * recursive completion), and chooseNext (distributional-evidence edge
135
+ * disambiguation when a recognised form has multiple continuations). */
136
+ private readonly host;
137
+ constructor(
138
+ store: Store,
139
+ maxGroup: number,
126
140
  /** The host whose capabilities the search consults: resolve (canonical node
127
141
  * id of a byte span), recogniseSpan (content-addressed graph lookup for
128
142
  * recursive completion), and chooseNext (distributional-evidence edge
129
143
  * disambiguation when a recognised form has multiple continuations). */
130
- host: GraphSearchHost);
131
- /** Explore the Sema graph for the lightest cover of the query and return its
132
- * chosen spans left-to-right WITH the derivation's total weight (the g
133
- * value of the goal item, in the exported cost ladder), which think's
134
- * grounding decider compares against the other mechanisms' candidates
135
- * or null if the query cannot be covered.
136
- *
137
- * The search runs on the query's tree leaves, not flat bytes — leaf-level
138
- * cover axioms, recognised forms as graph entry pointsand discovers
139
- * cross-leaf forms by fusing adjacent fragments on demand (the only
140
- * byte-processing it does, and only where a derivation needs it). When
141
- * `substitutions` is given, recognised forms emit substitute bytes directly
142
- * (cost 0) articulation splicing the asker's wording in.
143
- *
144
- * Any learnt connector between two rewrites is spliced IN by the in-search
145
- * connector rule (see {@link outRules}), so the returned spans already carry
146
- * it there is no post-pass. */
147
- cover(queryLen: number, sites: ReadonlyArray<Site>, conceptTarget: ReadonlyMap<number, number>, leaves: ReadonlyArray<Leaf>, splits: ReadonlySet<number>, substitutions?: ReadonlyMap<number, Uint8Array>, connectors?: ReadonlyMap<string, Uint8Array>, computedResults?: ReadonlyArray<ComputedResult>,
144
+ host: GraphSearchHost,
145
+ );
146
+ /** Explore the Sema graph for the lightest cover of the query and return its
147
+ * chosen spans left-to-right WITH the derivation's total weight (the g
148
+ * value of the goal item, in the exported cost ladder), which think's
149
+ * grounding decider compares against the other mechanisms' candidates
150
+ * or null if the query cannot be covered.
151
+ *
152
+ * The search runs on the query's tree leaves, not flat bytes leaf-level
153
+ * cover axioms, recognised forms as graph entry points and discovers
154
+ * cross-leaf forms by fusing adjacent fragments on demand (the only
155
+ * byte-processing it does, and only where a derivation needs it). When
156
+ * `substitutions` is given, recognised forms emit substitute bytes directly
157
+ * (cost 0) — articulation splicing the asker's wording in.
158
+ *
159
+ * Any learnt connector between two rewrites is spliced IN by the in-search
160
+ * connector rule (see {@link outRules}), so the returned spans already carry
161
+ * it there is no post-pass. */
162
+ cover(
163
+ queryLen: number,
164
+ sites: ReadonlyArray<Site>,
165
+ conceptTarget: ReadonlyMap<number, number>,
166
+ leaves: ReadonlyArray<Leaf>,
167
+ splits: ReadonlySet<number>,
168
+ substitutions?: ReadonlyMap<number, Uint8Array>,
169
+ connectors?: ReadonlyMap<string, Uint8Array>,
170
+ computedResults?: ReadonlyArray<ComputedResult>,
148
171
  /** When given, receives the lightest derivation's rule applications — the
149
172
  * full adapted A*LD proof tree as classified {@link DerivationStep}s — for the TOP
150
173
  * cover only (a recursive recompletion solves its own sub-cover and is not
151
174
  * reported here, to keep the trace one layer per think). Off by default,
152
175
  * so the search pays nothing when no one inspects. */
153
- onDerivation?: (steps: DerivationStep[]) => void): {
154
- segs: Seg[];
155
- cost: number;
156
- } | null;
157
- /** Build the deduction system for one span and return its lightest cover's
158
- * chosen spans the SINGLE routine the query and every produced composite
159
- * run through. `recognition` carries the span's recognised forms; the query
160
- * brings its own (with pre-resolved concepts/connectors), a recursive
161
- * completion re-recognises the produced bytes (edge/fuse only).
162
- *
163
- * No depth limit governs nesting — convergence is INTRINSIC, exactly as in the
164
- * adapted A*LD chart and {@link completeForward}: a completion only recurses into a
165
- * node it has not already entered ({@link recompleteNode}'s cycle guard), and
166
- * the node ids are finite, so the recursion must terminate on its own. A
167
- * decomposition may therefore run as deep as the graph licenses three
168
- * decomposes, two recomposes, any mix and stops only when it reaches a node
169
- * that leads nowhere new, never at an arbitrary count. */
170
- private solve;
171
- /** The weighted deduction system the graph exploration solves (the four
172
- * reductions of adapted A*LD live in {@link lightestDerivation}; this only states the
173
- * items, axioms, goal, and rules see {@link GItem} for the item kinds).
174
- *
175
- * Forms that span across leaves are discovered BY the rules, which fuse
176
- * adjacent fragments toward a known leaf (findLeaf) or branch (findBranch);
177
- * a completion fused with its neighbour may spell a deeper learned form the
178
- * flat probes can't name, recovered canonically by {@link resolve}. */
179
- private buildSearch;
180
- /** cover(p): the BRIDGE rule — extend the cover across any coverable out that
181
- * begins at p, stepping the frontier from p to that out's end.
182
- *
183
- * This is what links the rewritten parts of a multi-form answer. An out is
184
- * either a recognised completion (`rec`, free) or a literal span the query
185
- * carried between known forms the connective: a space, comma, period,
186
- * newline, or any run of bytes that was never recognised. Bridging a literal
187
- * costs PASS per byte (so the search still prefers to recognise), but it is
188
- * the cheapest indeed only way to cross a gap that has no learned form,
189
- * and it KEEPS that connective in the cover chain, so the asker's own linking
190
- * material reappears when it still coheres ("ice, fire" "cold, hot", not
191
- * "coldhot"). A recognised completion bridges for a tiny ε (1e-3, far below
192
- * STEP), so a single connected span beats two separate ones on coherence
193
- * without disturbing the cost ladder's ordering.
194
- *
195
- * Marks p finalised so the symmetric out-side bridge ({@link outRules}) can
196
- * fire for outs that arrive after their start position is covered. */
197
- private coverRules;
198
- /** The BRIDGE rule, built once for its two arrival orders (cover-first in
199
- * {@link coverRules}, out-first in {@link outRules}): ε for a recognised
200
- * completion; PASS per byte for a literal connective kept in the cover
201
- * so the asker's own connector survives where it fits. ONE definition of
202
- * the cost expression, so the ladder's application cannot drift between
203
- * the two sides. */
204
- private bridgeRule;
205
- /** The connector-SPLICE rule for an oriented (l, r) pair, or null when the
206
- * pair does not qualify the ONE body behind {@link outRules}' two
207
- * mirror loops (this-as-left over resolved right partners, this-as-right
208
- * over resolved left partners). Fires only when both sides are
209
- * recognised, r starts at or after l ends, and the gap between them is
210
- * empty or wholly recognised never across the asker's own literal
211
- * separator. */
212
- private trySplice;
213
- /** form(i,j,node,via): follow the graph out of `node`, or (in articulation)
214
- * emit its substitute voice directly. */
215
- private formRules;
216
- /** Complete a node that an edge produced but that bears no further whole-edge,
217
- * by COVERING ITS OWN BYTES the very same operation the top query runs.
218
- * Completion is not a special pass: a produced composite ("p1 p2") is just
219
- * another span to cover, and covering it re-applies recognition, edge-follow,
220
- * fusion and recomposition to discover that its parts continue (p1→R1, p2→R2)
221
- * and recompose into a deeper learnt form (→ FINAL). This is why a single
222
- * edge-target needs no bespoke logic it routes back through {@link solve}.
223
- *
224
- * Re-recognition (not the node's tree children) is what surfaces the learnt
225
- * parts: content-defined chunking may cut "p1 p2" as "p1 p"|"2", so only
226
- * recognising the bytes recovers p1 and p2 as the forms the graph knows.
227
- *
228
- * The recovered answer is accepted only when it MOVED and names a LEARNT node
229
- * ({@link resolve}) the graph itself gates against re-expanding a contained
230
- * form ("ice is cold" ⊅→ "ice is cold is cold").
231
- *
232
- * Termination is INTRINSIC, not a depth limit: a node already on the
233
- * completion stack ({@link recompleteOpen}) is not re-entered a self-
234
- * referential recomposition is a cycle that can yield nothing new, so it
235
- * stops there, exactly as {@link completeForward} stops on a revisited edge.
236
- * Distinct node ids are finite and each finished completion is memoised, so a
237
- * legitimate chain runs as deep as the graph licenses and no further. */
238
- private recompleteNode;
239
- /** Per-cover memo of each produced node's completion (so the many terminal
240
- * outs of a long query re-cover each distinct node at most once); reset at the
241
- * top of {@link cover}. */
242
- private recompleteMemo;
243
- /** The nodes currently being re-completed — the recursion stack. A node in
244
- * this set is not re-entered, so a cyclic recomposition terminates naturally
245
- * (the same cycle guard {@link completeForward} uses), with no depth cap. */
246
- private recompleteOpen;
247
- /** out(i,j,bytes,…): index it for the binary rules, then offer splicing a
248
- * learnt connector (the in-search bridge), splitting (at a sub-leaf form
249
- * boundary), bridging (cover(i) this cover(j)), and fusing with an
250
- * adjacent finalised out. */
251
- private outRules;
252
- /** Whether the query span [from, to) is wholly covered by RECOGNISED outs —
253
- * the test that lets a connector jump across INTERIOR answers (an N-ary whole)
254
- * but never across the asker's own unrecognised framing (a space or comma the
255
- * asker wrote between parts). Empty span (from === to, the adjacent case) is
256
- * trivially recognised. Otherwise step right-to-left: from `to`, find a
257
- * recognised out ending there and continue from its start, until reaching
258
- * `from`. Greedy-longest is sufficient here the spans in play are the few
259
- * recognised answers of one query, not a general interval cover. */
260
- private gapRecognised;
261
- /** Fuse two adjacent finalised outs — the search's own discovery of forms
262
- * that cross leaf boundaries. The concatenation may be a known leaf
263
- * (findLeaf, when short enough), or when both sides resolved — their pair a
264
- * known branch (findBranch); a completion fused with its neighbour may spell
265
- * a deeper learned form, recovered canonically by {@link resolve} (gated on a
266
- * completion being present, so it only runs along chains). The fused span
267
- * lives on as an intermediate out while it could still grow into a form, and
268
- * enters the graph as a form the moment it names a node. */
269
- private fuse;
176
+ onDerivation?: (steps: DerivationStep[]) => void,
177
+ ): {
178
+ segs: Seg[];
179
+ cost: number;
180
+ } | null;
181
+ /** Build the deduction system for one span and return its lightest cover's
182
+ * chosen spans the SINGLE routine the query and every produced composite
183
+ * run through. `recognition` carries the span's recognised forms; the query
184
+ * brings its own (with pre-resolved concepts/connectors), a recursive
185
+ * completion re-recognises the produced bytes (edge/fuse only).
186
+ *
187
+ * No depth limit governs nesting convergence is INTRINSIC, exactly as in the
188
+ * adapted A*LD chart and {@link completeForward}: a completion only recurses into a
189
+ * node it has not already entered ({@link recompleteNode}'s cycle guard), and
190
+ * the node ids are finite, so the recursion must terminate on its own. A
191
+ * decomposition may therefore run as deep as the graph licenses three
192
+ * decomposes, two recomposes, any mix and stops only when it reaches a node
193
+ * that leads nowhere new, never at an arbitrary count. */
194
+ private solve;
195
+ /** The weighted deduction system the graph exploration solves (the four
196
+ * reductions of adapted A*LD live in {@link lightestDerivation}; this only states the
197
+ * items, axioms, goal, and rules — see {@link GItem} for the item kinds).
198
+ *
199
+ * Forms that span across leaves are discovered BY the rules, which fuse
200
+ * adjacent fragments toward a known leaf (findLeaf) or branch (findBranch);
201
+ * a completion fused with its neighbour may spell a deeper learned form the
202
+ * flat probes can't name, recovered canonically by {@link resolve}. */
203
+ private buildSearch;
204
+ /** cover(p): the BRIDGE rule — extend the cover across any coverable out that
205
+ * begins at p, stepping the frontier from p to that out's end.
206
+ *
207
+ * This is what links the rewritten parts of a multi-form answer. An out is
208
+ * either a recognised completion (`rec`, free) or a literal span the query
209
+ * carried between known forms the connective: a space, comma, period,
210
+ * newline, or any run of bytes that was never recognised. Bridging a literal
211
+ * costs PASS per byte (so the search still prefers to recognise), but it is
212
+ * the cheapest indeed only way to cross a gap that has no learned form,
213
+ * and it KEEPS that connective in the cover chain, so the asker's own linking
214
+ * material reappears when it still coheres ("ice, fire" → "cold, hot", not
215
+ * "coldhot"). A recognised completion bridges for a tiny ε (1e-3, far below
216
+ * STEP), so a single connected span beats two separate ones on coherence
217
+ * without disturbing the cost ladder's ordering.
218
+ *
219
+ * Marks p finalised so the symmetric out-side bridge ({@link outRules}) can
220
+ * fire for outs that arrive after their start position is covered. */
221
+ private coverRules;
222
+ /** The BRIDGE rule, built once for its two arrival orders (cover-first in
223
+ * {@link coverRules}, out-first in {@link outRules}): ε for a recognised
224
+ * completion; PASS per byte for a literal connective kept in the cover
225
+ * so the asker's own connector survives where it fits. ONE definition of
226
+ * the cost expression, so the ladder's application cannot drift between
227
+ * the two sides. */
228
+ private bridgeRule;
229
+ /** The connector-SPLICE rule for an oriented (l, r) pair, or null when the
230
+ * pair does not qualify the ONE body behind {@link outRules}' two
231
+ * mirror loops (this-as-left over resolved right partners, this-as-right
232
+ * over resolved left partners). Fires only when both sides are
233
+ * recognised, r starts at or after l ends, and the gap between them is
234
+ * empty or wholly recognised — never across the asker's own literal
235
+ * separator. */
236
+ private trySplice;
237
+ /** form(i,j,node,via): follow the graph out of `node`, or (in articulation)
238
+ * emit its substitute voice directly. */
239
+ private formRules;
240
+ /** Complete a node that an edge produced but that bears no further whole-edge,
241
+ * by COVERING ITS OWN BYTES the very same operation the top query runs.
242
+ * Completion is not a special pass: a produced composite ("p1 p2") is just
243
+ * another span to cover, and covering it re-applies recognition, edge-follow,
244
+ * fusion and recomposition to discover that its parts continue (p1R1, p2→R2)
245
+ * and recompose into a deeper learnt form (→ FINAL). This is why a single
246
+ * edge-target needs no bespoke logic — it routes back through {@link solve}.
247
+ *
248
+ * Re-recognition (not the node's tree children) is what surfaces the learnt
249
+ * parts: content-defined chunking may cut "p1 p2" as "p1 p"|"2", so only
250
+ * recognising the bytes recovers p1 and p2 as the forms the graph knows.
251
+ *
252
+ * The recovered answer is accepted only when it MOVED and names a LEARNT node
253
+ * ({@link resolve}) the graph itself gates against re-expanding a contained
254
+ * form ("ice is cold" ⊅→ "ice is cold is cold").
255
+ *
256
+ * Termination is INTRINSIC, not a depth limit: a node already on the
257
+ * completion stack ({@link recompleteOpen}) is not re-entered a self-
258
+ * referential recomposition is a cycle that can yield nothing new, so it
259
+ * stops there, exactly as {@link completeForward} stops on a revisited edge.
260
+ * Distinct node ids are finite and each finished completion is memoised, so a
261
+ * legitimate chain runs as deep as the graph licenses and no further. */
262
+ private recompleteNode;
263
+ /** Per-cover memo of each produced node's completion (so the many terminal
264
+ * outs of a long query re-cover each distinct node at most once); reset at the
265
+ * top of {@link cover}. */
266
+ private recompleteMemo;
267
+ /** The nodes currently being re-completed the recursion stack. A node in
268
+ * this set is not re-entered, so a cyclic recomposition terminates naturally
269
+ * (the same cycle guard {@link completeForward} uses), with no depth cap. */
270
+ private recompleteOpen;
271
+ /** out(i,j,bytes,…): index it for the binary rules, then offer splicing a
272
+ * learnt connector (the in-search bridge), splitting (at a sub-leaf form
273
+ * boundary), bridging (cover(i) ∧ this → cover(j)), and fusing with an
274
+ * adjacent finalised out. */
275
+ private outRules;
276
+ /** Whether the query span [from, to) is wholly covered by RECOGNISED outs
277
+ * the test that lets a connector jump across INTERIOR answers (an N-ary whole)
278
+ * but never across the asker's own unrecognised framing (a space or comma the
279
+ * asker wrote between parts). Empty span (from === to, the adjacent case) is
280
+ * trivially recognised. Otherwise step right-to-left: from `to`, find a
281
+ * recognised out ending there and continue from its start, until reaching
282
+ * `from`. Greedy-longest is sufficient here the spans in play are the few
283
+ * recognised answers of one query, not a general interval cover. */
284
+ private gapRecognised;
285
+ /** Fuse two adjacent finalised outs the search's own discovery of forms
286
+ * that cross leaf boundaries. The concatenation may be a known leaf
287
+ * (findLeaf, when short enough), or when both sides resolved their pair a
288
+ * known branch (findBranch); a completion fused with its neighbour may spell
289
+ * a deeper learned form, recovered canonically by {@link resolve} (gated on a
290
+ * completion being present, so it only runs along chains). The fused span
291
+ * lives on as an intermediate out while it could still grow into a form, and
292
+ * enters the graph as a form the moment it names a node. */
293
+ private fuse;
270
294
  }