@hviana/sema 0.1.3 → 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 (123) 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 +35 -0
  115. package/dist/src/sema.js +77 -0
  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
  123. package/src/sema.ts +102 -0
@@ -39,170 +39,210 @@ import { asBit, asInt, int, isNd, nd } from "./value.js";
39
39
  /** The element list of an nd, or throw — so a structural op called on a non-list
40
40
  * declines (the Alu facade maps the throw to "this rule does not fire"). */
41
41
  function listOf(v) {
42
- if (!isNd(v))
43
- throw new Error("nd op: operand is not an n-dimensional value");
44
- return v.items;
42
+ if (!isNd(v)) {
43
+ throw new Error("nd op: operand is not an n-dimensional value");
44
+ }
45
+ return v.items;
45
46
  }
46
47
  /** Resolve an operation-value to a canonical name of the wanted arity, or throw
47
48
  * (decline) when it names no known operation — the higher-order ops' shared
48
49
  * front door, so an unrecognised function argument never silently no-ops. */
49
50
  function resolveFn(ctx, op, arity) {
50
- const name = ctx.resolveOp(op, arity);
51
- if (name === null)
52
- throw new Error("nd op: unrecognised operation argument");
53
- return name;
51
+ const name = ctx.resolveOp(op, arity);
52
+ if (name === null) {
53
+ throw new Error("nd op: unrecognised operation argument");
54
+ }
55
+ return name;
54
56
  }
55
57
  /** Register the n-dimensional layer into `r`. All ops are STRUCTURAL. */
56
58
  export function registerNd(r) {
57
- // ── core primitives (the only ops that touch `items`) ────────────────────
58
- // nd: PACK operands into a list. Variadic, so `nd(a, b, c)` = [a, b, c] and
59
- // `nd()` = the empty list. An operand that is itself a list nests (a matrix
60
- // is `nd(row0, row1, …)`), so rank grows by composition, never a new type.
61
- r.prim("nd", "variadic", ["nd", "list", "vector", "tuple", "array"], (args) => nd(args.slice()), { structural: true });
62
- // length: the top-level element count, as an exact int.
63
- r.prim("length", 1, ["length", "size", "len"], (args) => int(BigInt(listOf(args[0]).length)), { structural: true });
64
- // at: project the i-th element. A negative index counts from the end
65
- // (−1 = last), Python-style; out of range throws (the rule declines).
66
- r.prim("at", 2, ["at", "nth", "elem", "index"], (args) => {
67
- const xs = listOf(args[0]);
68
- let i = Number(asInt(args[1]));
69
- if (i < 0)
70
- i += xs.length;
71
- if (i < 0 || i >= xs.length)
72
- throw new Error("at: index out of range");
73
- return xs[i];
74
- }, { structural: true });
75
- // ── derived: construction ────────────────────────────────────────────────
76
- // range(n) = [0, 1, …, n−1]; range(a, b) = [a, a+1, …, b−1]. The index
77
- // generator map/reduce iterate over when there is no input list yet.
78
- r.derive("range", "variadic", ["range", "iota", "upto"], (args) => {
79
- const lo = args.length >= 2 ? asInt(args[0]) : 0n;
80
- const hi = args.length >= 2 ? asInt(args[1]) : asInt(args[0]);
81
- const out = [];
82
- for (let k = lo; k < hi; k++)
83
- out.push(int(k));
84
- return nd(out);
85
- }, { structural: true });
86
- // ── derived: the higher-order trio (op argument = any existing operation) ──
87
- // map(xs, f): apply the UNARY op f to each element. Built on at/length/nd; f
88
- // is resolved by meaning, so `map(xs, negate)`, `map(xs, sqrt)`, `map(xs,
89
- // inverse)` all work, and (via broadcast) map over a list of lists is fine.
90
- r.derive("map", 2, ["map", "each"], (args, ctx) => {
91
- const xs = listOf(args[0]);
92
- const f = resolveFn(ctx, args[1], 1);
93
- return nd(xs.map((e) => ctx.apply(f, [e])));
94
- }, { structural: true });
95
- // filter(xs, p): keep the elements for which the UNARY predicate p is truthy
96
- // (its result read as a bit). `filter(xs, isprime)`, `filter(xs, >0)`, … —
97
- // any op that returns a truth value is a predicate.
98
- r.derive("filter", 2, ["filter", "where", "keep"], (args, ctx) => {
99
- const xs = listOf(args[0]);
100
- const p = resolveFn(ctx, args[1], 1);
101
- return nd(xs.filter((e) => asBit(ctx.apply(p, [e])) === 1));
102
- }, { structural: true });
103
- // reduce(xs, f) / reduce(xs, f, z): left-fold the BINARY op f across the list,
104
- // optionally from a seed z. `reduce(xs, +)` sums, `reduce(xs, *)` multiplies,
105
- // `reduce(xs, max)` is the maximum, `reduce(xs, or)` is "any", the scalar
106
- // kernel's whole binary vocabulary becomes a fold. With no seed an empty list
107
- // declines (nothing to fold); with a seed it returns the seed.
108
- r.derive("reduce", "variadic", ["reduce", "fold", "accumulate"], (args, ctx) => {
109
- if (args.length < 2) {
110
- throw new Error("reduce: needs a list and an operation");
59
+ // ── core primitives (the only ops that touch `items`) ────────────────────
60
+ // nd: PACK operands into a list. Variadic, so `nd(a, b, c)` = [a, b, c] and
61
+ // `nd()` = the empty list. An operand that is itself a list nests (a matrix
62
+ // is `nd(row0, row1, …)`), so rank grows by composition, never a new type.
63
+ r.prim(
64
+ "nd",
65
+ "variadic",
66
+ ["nd", "list", "vector", "tuple", "array"],
67
+ (args) => nd(args.slice()),
68
+ { structural: true },
69
+ );
70
+ // length: the top-level element count, as an exact int.
71
+ r.prim(
72
+ "length",
73
+ 1,
74
+ ["length", "size", "len"],
75
+ (args) => int(BigInt(listOf(args[0]).length)),
76
+ { structural: true },
77
+ );
78
+ // at: project the i-th element. A negative index counts from the end
79
+ // (−1 = last), Python-style; out of range throws (the rule declines).
80
+ r.prim("at", 2, ["at", "nth", "elem", "index"], (args) => {
81
+ const xs = listOf(args[0]);
82
+ let i = Number(asInt(args[1]));
83
+ if (i < 0) {
84
+ i += xs.length;
85
+ }
86
+ if (i < 0 || i >= xs.length) {
87
+ throw new Error("at: index out of range");
88
+ }
89
+ return xs[i];
90
+ }, { structural: true });
91
+ // ── derived: construction ────────────────────────────────────────────────
92
+ // range(n) = [0, 1, …, n−1]; range(a, b) = [a, a+1, …, b−1]. The index
93
+ // generator map/reduce iterate over when there is no input list yet.
94
+ r.derive("range", "variadic", ["range", "iota", "upto"], (args) => {
95
+ const lo = args.length >= 2 ? asInt(args[0]) : 0n;
96
+ const hi = args.length >= 2 ? asInt(args[1]) : asInt(args[0]);
97
+ const out = [];
98
+ for (let k = lo; k < hi; k++) {
99
+ out.push(int(k));
100
+ }
101
+ return nd(out);
102
+ }, { structural: true });
103
+ // ── derived: the higher-order trio (op argument = any existing operation) ──
104
+ // map(xs, f): apply the UNARY op f to each element. Built on at/length/nd; f
105
+ // is resolved by meaning, so `map(xs, negate)`, `map(xs, sqrt)`, `map(xs,
106
+ // inverse)` all work, and (via broadcast) map over a list of lists is fine.
107
+ r.derive("map", 2, ["map", "each"], (args, ctx) => {
108
+ const xs = listOf(args[0]);
109
+ const f = resolveFn(ctx, args[1], 1);
110
+ return nd(xs.map((e) => ctx.apply(f, [e])));
111
+ }, { structural: true });
112
+ // filter(xs, p): keep the elements for which the UNARY predicate p is truthy
113
+ // (its result read as a bit). `filter(xs, isprime)`, `filter(xs, >0)`, … —
114
+ // any op that returns a truth value is a predicate.
115
+ r.derive("filter", 2, ["filter", "where", "keep"], (args, ctx) => {
116
+ const xs = listOf(args[0]);
117
+ const p = resolveFn(ctx, args[1], 1);
118
+ return nd(xs.filter((e) => asBit(ctx.apply(p, [e])) === 1));
119
+ }, { structural: true });
120
+ // reduce(xs, f) / reduce(xs, f, z): left-fold the BINARY op f across the list,
121
+ // optionally from a seed z. `reduce(xs, +)` sums, `reduce(xs, *)` multiplies,
122
+ // `reduce(xs, max)` is the maximum, `reduce(xs, or)` is "any", … — the scalar
123
+ // kernel's whole binary vocabulary becomes a fold. With no seed an empty list
124
+ // declines (nothing to fold); with a seed it returns the seed.
125
+ r.derive(
126
+ "reduce",
127
+ "variadic",
128
+ ["reduce", "fold", "accumulate"],
129
+ (args, ctx) => {
130
+ if (args.length < 2) {
131
+ throw new Error("reduce: needs a list and an operation");
132
+ }
133
+ const xs = listOf(args[0]);
134
+ const f = resolveFn(ctx, args[1], 2);
135
+ const hasSeed = args.length >= 3;
136
+ let acc;
137
+ let start;
138
+ if (hasSeed) {
139
+ acc = args[2];
140
+ start = 0;
141
+ } else {
142
+ if (xs.length === 0) {
143
+ throw new Error("reduce: empty list, no seed");
111
144
  }
112
- const xs = listOf(args[0]);
113
- const f = resolveFn(ctx, args[1], 2);
114
- const hasSeed = args.length >= 3;
115
- let acc;
116
- let start;
117
- if (hasSeed) {
118
- acc = args[2];
119
- start = 0;
145
+ acc = xs[0];
146
+ start = 1;
147
+ }
148
+ for (let i = start; i < xs.length; i++) {
149
+ acc = ctx.apply(f, [acc, xs[i]]);
150
+ }
151
+ return acc;
152
+ },
153
+ { structural: true },
154
+ );
155
+ // find(xs, p): the FIRST element satisfying the unary predicate p, or the
156
+ // empty nd when none does (a graph-evidenced "nothing matched", never a guess).
157
+ r.derive("find", 2, ["find", "first", "search"], (args, ctx) => {
158
+ const xs = listOf(args[0]);
159
+ const p = resolveFn(ctx, args[1], 1);
160
+ for (const e of xs) {
161
+ if (asBit(ctx.apply(p, [e])) === 1) {
162
+ return e;
163
+ }
164
+ }
165
+ return nd([]);
166
+ }, { structural: true });
167
+ // ── derived: shape-preserving plumbing ────────────────────────────────────
168
+ // concat(a, b, …): join lists end to end into one list.
169
+ r.derive("concat", "variadic", ["concat", "append", "join"], (args) => {
170
+ const out = [];
171
+ for (const a of args) {
172
+ for (const e of listOf(a)) {
173
+ out.push(e);
174
+ }
175
+ }
176
+ return nd(out);
177
+ }, { structural: true });
178
+ // reverse(xs): the list back to front.
179
+ r.derive(
180
+ "reverse",
181
+ 1,
182
+ ["reverse", "flip"],
183
+ (args) => nd(listOf(args[0]).slice().reverse()),
184
+ { structural: true },
185
+ );
186
+ // flatten(xs): splice one level — each nd element is spliced in, each scalar
187
+ // kept. flatten ∘ flatten goes deeper; one level is the primitive step.
188
+ r.derive("flatten", 1, ["flatten", "flat"], (args) => {
189
+ const out = [];
190
+ for (const e of listOf(args[0])) {
191
+ if (isNd(e)) {
192
+ for (const sub of e.items) {
193
+ out.push(sub);
120
194
  }
121
- else {
122
- if (xs.length === 0)
123
- throw new Error("reduce: empty list, no seed");
124
- acc = xs[0];
125
- start = 1;
195
+ } else {
196
+ out.push(e);
197
+ }
198
+ }
199
+ return nd(out);
200
+ }, { structural: true });
201
+ // zip(a, b, …): the lists braided into a list of tuples; length = the shortest
202
+ // input (a ragged braid stops at the short one, never inventing elements).
203
+ r.derive("zip", "variadic", ["zip", "braid"], (args) => {
204
+ const lists = args.map(listOf);
205
+ if (lists.length === 0) {
206
+ return nd([]);
207
+ }
208
+ const m = Math.min(...lists.map((l) => l.length));
209
+ const out = [];
210
+ for (let i = 0; i < m; i++) {
211
+ out.push(nd(lists.map((l) => l[i])));
212
+ }
213
+ return nd(out);
214
+ }, { structural: true });
215
+ // rank(v): the nesting DEPTH — 0 for a scalar, 1 + the deepest element's rank
216
+ // for a list (so a vector is 1, a matrix 2, ragged depth taken as the max).
217
+ r.derive("rank", 1, ["rank", "depth", "ndim"], (args) => {
218
+ const rank = (v) => {
219
+ if (!isNd(v)) {
220
+ return 0n;
221
+ }
222
+ let m = 0n;
223
+ for (const e of v.items) {
224
+ const rr = rank(e);
225
+ if (rr > m) {
226
+ m = rr;
126
227
  }
127
- for (let i = start; i < xs.length; i++)
128
- acc = ctx.apply(f, [acc, xs[i]]);
129
- return acc;
130
- }, { structural: true });
131
- // find(xs, p): the FIRST element satisfying the unary predicate p, or the
132
- // empty nd when none does (a graph-evidenced "nothing matched", never a guess).
133
- r.derive("find", 2, ["find", "first", "search"], (args, ctx) => {
134
- const xs = listOf(args[0]);
135
- const p = resolveFn(ctx, args[1], 1);
136
- for (const e of xs)
137
- if (asBit(ctx.apply(p, [e])) === 1)
138
- return e;
139
- return nd([]);
140
- }, { structural: true });
141
- // ── derived: shape-preserving plumbing ────────────────────────────────────
142
- // concat(a, b, …): join lists end to end into one list.
143
- r.derive("concat", "variadic", ["concat", "append", "join"], (args) => {
144
- const out = [];
145
- for (const a of args)
146
- for (const e of listOf(a))
147
- out.push(e);
148
- return nd(out);
149
- }, { structural: true });
150
- // reverse(xs): the list back to front.
151
- r.derive("reverse", 1, ["reverse", "flip"], (args) => nd(listOf(args[0]).slice().reverse()), { structural: true });
152
- // flatten(xs): splice one level — each nd element is spliced in, each scalar
153
- // kept. flatten ∘ flatten goes deeper; one level is the primitive step.
154
- r.derive("flatten", 1, ["flatten", "flat"], (args) => {
155
- const out = [];
156
- for (const e of listOf(args[0])) {
157
- if (isNd(e)) {
158
- for (const sub of e.items)
159
- out.push(sub);
160
- }
161
- else
162
- out.push(e);
163
- }
164
- return nd(out);
165
- }, { structural: true });
166
- // zip(a, b, …): the lists braided into a list of tuples; length = the shortest
167
- // input (a ragged braid stops at the short one, never inventing elements).
168
- r.derive("zip", "variadic", ["zip", "braid"], (args) => {
169
- const lists = args.map(listOf);
170
- if (lists.length === 0)
171
- return nd([]);
172
- const m = Math.min(...lists.map((l) => l.length));
173
- const out = [];
174
- for (let i = 0; i < m; i++)
175
- out.push(nd(lists.map((l) => l[i])));
176
- return nd(out);
177
- }, { structural: true });
178
- // rank(v): the nesting DEPTH — 0 for a scalar, 1 + the deepest element's rank
179
- // for a list (so a vector is 1, a matrix 2, ragged depth taken as the max).
180
- r.derive("rank", 1, ["rank", "depth", "ndim"], (args) => {
181
- const rank = (v) => {
182
- if (!isNd(v))
183
- return 0n;
184
- let m = 0n;
185
- for (const e of v.items) {
186
- const rr = rank(e);
187
- if (rr > m)
188
- m = rr;
189
- }
190
- return m + 1n;
191
- };
192
- return int(rank(args[0]));
193
- }, { structural: true });
194
- // shape(v): the size along each axis, following the FIRST element down — the
195
- // regular-tensor shape (a ragged list is reported by its top length, the
196
- // recursion only descending the head). Returns a list of ints.
197
- r.derive("shape", 1, ["shape", "dims"], (args) => {
198
- const dims = [];
199
- let cur = args[0];
200
- while (isNd(cur)) {
201
- dims.push(int(BigInt(cur.items.length)));
202
- if (cur.items.length === 0)
203
- break;
204
- cur = cur.items[0];
205
- }
206
- return nd(dims);
207
- }, { structural: true });
228
+ }
229
+ return m + 1n;
230
+ };
231
+ return int(rank(args[0]));
232
+ }, { structural: true });
233
+ // shape(v): the size along each axis, following the FIRST element down — the
234
+ // regular-tensor shape (a ragged list is reported by its top length, the
235
+ // recursion only descending the head). Returns a list of ints.
236
+ r.derive("shape", 1, ["shape", "dims"], (args) => {
237
+ const dims = [];
238
+ let cur = args[0];
239
+ while (isNd(cur)) {
240
+ dims.push(int(BigInt(cur.items.length)));
241
+ if (cur.items.length === 0) {
242
+ break;
243
+ }
244
+ cur = cur.items[0];
245
+ }
246
+ return nd(dims);
247
+ }, { structural: true });
208
248
  }
@@ -3,51 +3,115 @@ import type { OperationRegistry } from "./operation.js";
3
3
  * agree within `tol` (absolute, or relative for large magnitudes), or until
4
4
  * `maxIter` is reached. Returns the last iterate — the refinement's fixed
5
5
  * point. This is the single irreducible operator of the numerical layer. */
6
- export declare function converge(step: (x: number) => number, x0: number, tol: number, maxIter: number): number;
6
+ export declare function converge(
7
+ step: (x: number) => number,
8
+ x0: number,
9
+ tol: number,
10
+ maxIter: number,
11
+ ): number;
7
12
  /** Numerical derivative f′(a) by a central difference refined as h → 0 — a
8
13
  * `converge` instance over shrinking step sizes (Richardson-style halving). */
9
- export declare function diff(f: (x: number) => number, a: number, tol: number, maxIter: number): number;
14
+ export declare function diff(
15
+ f: (x: number) => number,
16
+ a: number,
17
+ tol: number,
18
+ maxIter: number,
19
+ ): number;
10
20
  /** A root of f near x0, by Newton's method: converge x − f(x)/f′(x), with f′
11
21
  * from {@link diff}. Falls back to a secant step if the derivative vanishes. */
12
- export declare function solve(f: (x: number) => number, x0: number, tol: number, maxIter: number): number;
22
+ export declare function solve(
23
+ f: (x: number) => number,
24
+ x0: number,
25
+ tol: number,
26
+ maxIter: number,
27
+ ): number;
13
28
  /** Definite integral of f over [a, b], by composite Simpson refined until the
14
29
  * estimate stops moving — a `converge` over partition count. */
15
- export declare function integrate(f: (x: number) => number, a: number, b: number, tol: number, maxIter: number): number;
30
+ export declare function integrate(
31
+ f: (x: number) => number,
32
+ a: number,
33
+ b: number,
34
+ tol: number,
35
+ maxIter: number,
36
+ ): number;
16
37
  /** e^x by its Taylor series, summed until a term is below tolerance — a
17
38
  * `converge` over partial sums. (Range-reduction-free; adequate for the
18
39
  * arguments a query produces, and exact in the limit.) */
19
- export declare function expSeries(x: number, tol: number, maxIter: number): number;
40
+ export declare function expSeries(
41
+ x: number,
42
+ tol: number,
43
+ maxIter: number,
44
+ ): number;
20
45
  /** ln(x), x > 0, as the root of e^t − x = 0 (Newton via {@link solve}, with a
21
46
  * good initial guess from the host log to keep iteration counts low). */
22
- export declare function logNewton(x: number, tol: number, maxIter: number): number;
47
+ export declare function logNewton(
48
+ x: number,
49
+ tol: number,
50
+ maxIter: number,
51
+ ): number;
23
52
  /** sin / cos by their Taylor series (a `converge` over partial sums), with
24
53
  * argument reduction into [−π, π] for accuracy. */
25
- export declare function sinSeries(x: number, tol: number, maxIter: number): number;
26
- export declare function cosSeries(x: number, tol: number, maxIter: number): number;
54
+ export declare function sinSeries(
55
+ x: number,
56
+ tol: number,
57
+ maxIter: number,
58
+ ): number;
59
+ export declare function cosSeries(
60
+ x: number,
61
+ tol: number,
62
+ maxIter: number,
63
+ ): number;
27
64
  /** √x as the positive root of t² − x = 0 (Newton via {@link solve}). */
28
- export declare function sqrtNewton(x: number, tol: number, maxIter: number): number;
65
+ export declare function sqrtNewton(
66
+ x: number,
67
+ tol: number,
68
+ maxIter: number,
69
+ ): number;
29
70
  /** A local minimum of f near x0: a root of f′ = 0 (optimize = solve(diff f)). */
30
- export declare function optimize(f: (x: number) => number, x0: number, tol: number, maxIter: number): number;
71
+ export declare function optimize(
72
+ f: (x: number) => number,
73
+ x0: number,
74
+ tol: number,
75
+ maxIter: number,
76
+ ): number;
31
77
  /** Integrate an ODE y′ = f(t, y) from (t0, y0) to t1 by classical RK4 stepping
32
78
  * — explicit stepping is the layer's other use of refinement (here a fixed
33
79
  * fine step; an implicit step would close with {@link solve}). */
34
- export declare function odeSolve(f: (t: number, y: number) => number, t0: number, y0: number, t1: number, steps?: number): number;
80
+ export declare function odeSolve(
81
+ f: (t: number, y: number) => number,
82
+ t0: number,
83
+ y0: number,
84
+ t1: number,
85
+ steps?: number,
86
+ ): number;
35
87
  /** Least-squares polynomial regression of degree `deg` over (x, y) samples:
36
88
  * build the normal equations and solve them with {@link linsolve} — regression
37
89
  * reduces to structured arithmetic. Returns coefficients constant-first. */
38
- export declare function regress(xs: number[], ys: number[], deg: number): number[] | null;
90
+ export declare function regress(
91
+ xs: number[],
92
+ ys: number[],
93
+ deg: number,
94
+ ): number[] | null;
39
95
  /** Linear interpolation of y at `xq` over sorted sample points (xs, ys). */
40
- export declare function interpolate(xs: number[], ys: number[], xq: number): number;
96
+ export declare function interpolate(
97
+ xs: number[],
98
+ ys: number[],
99
+ xq: number,
100
+ ): number;
41
101
  /** Dominant eigenpair of a (preferably symmetric) matrix by POWER ITERATION —
42
102
  * the canonical "iteration = converge" of this layer. Returns the eigenvalue
43
103
  * (Rayleigh quotient) and its unit eigenvector. */
44
104
  export declare function powerEig(A: number[][], tol: number, maxIter: number): {
45
- value: number;
46
- vector: number[];
105
+ value: number;
106
+ vector: number[];
47
107
  };
48
108
  /** Largest singular value of A: √(dominant eigenvalue of AᵀA) — power iteration
49
109
  * again, the prototypical `converge`. */
50
- export declare function topSingular(A: number[][], tol: number, maxIter: number): number;
110
+ export declare function topSingular(
111
+ A: number[][],
112
+ tol: number,
113
+ maxIter: number,
114
+ ): number;
51
115
  /** Register the scalar transcendentals as ops (they have surface forms). The
52
116
  * matrix routines stay exported functions — there is no infix surface for a
53
117
  * matrix, and auto-firing them from query spans is neither wanted nor safe. */