@hviana/sema 0.1.5 → 0.1.7
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 +6 -5
- package/CITATION.cff +49 -0
- package/HOW_IT_WORKS.md +11 -12
- package/README.md +7 -5
- package/dist/example/demo.js +25 -25
- package/dist/example/train_base.d.ts +19 -21
- package/dist/example/train_base.js +1700 -1952
- package/dist/src/alphabet.d.ts +3 -3
- package/dist/src/alphabet.js +24 -27
- package/dist/src/alu/src/alu.d.ts +169 -194
- package/dist/src/alu/src/alu.js +374 -414
- package/dist/src/alu/src/expr.d.ts +36 -43
- package/dist/src/alu/src/expr.js +252 -278
- package/dist/src/alu/src/index.d.ts +9 -98
- package/dist/src/alu/src/index.js +10 -64
- package/dist/src/alu/src/kernel-arith.d.ts +1 -5
- package/dist/src/alu/src/kernel-arith.js +195 -285
- package/dist/src/alu/src/kernel-bits.d.ts +1 -5
- package/dist/src/alu/src/kernel-bits.js +81 -115
- package/dist/src/alu/src/kernel-logic.js +33 -63
- package/dist/src/alu/src/kernel-nd.js +155 -195
- package/dist/src/alu/src/kernel-numeric.d.ts +16 -80
- package/dist/src/alu/src/kernel-numeric.js +259 -331
- package/dist/src/alu/src/operation.d.ts +112 -132
- package/dist/src/alu/src/operation.js +149 -163
- package/dist/src/alu/src/parser.d.ts +168 -175
- package/dist/src/alu/src/parser.js +382 -421
- package/dist/src/alu/src/resonance.d.ts +16 -25
- package/dist/src/alu/src/resonance.js +49 -56
- package/dist/src/alu/src/text.d.ts +3 -7
- package/dist/src/alu/src/text.js +31 -37
- package/dist/src/alu/src/value.d.ts +14 -14
- package/dist/src/alu/src/value.js +150 -160
- package/dist/src/alu/test/alu.test.js +543 -656
- package/dist/src/bytes.d.ts +1 -5
- package/dist/src/bytes.js +33 -40
- package/dist/src/config.d.ts +99 -102
- package/dist/src/config.js +78 -83
- package/dist/src/derive/src/deduction.d.ts +60 -62
- package/dist/src/derive/src/deduction.js +103 -109
- package/dist/src/derive/src/index.d.ts +1 -7
- package/dist/src/derive/src/priority-queue.d.ts +8 -8
- package/dist/src/derive/src/priority-queue.js +57 -61
- package/dist/src/derive/src/rewrite.d.ts +15 -18
- package/dist/src/derive/src/rewrite.js +59 -67
- package/dist/src/derive/src/trie.d.ts +56 -56
- package/dist/src/derive/src/trie.js +175 -179
- package/dist/src/derive/test/derive.test.js +96 -100
- package/dist/src/extension.d.ts +13 -16
- package/dist/src/geometry.d.ts +29 -43
- package/dist/src/geometry.js +324 -268
- package/dist/src/index.d.ts +2 -17
- package/dist/src/index.js +2 -12
- package/dist/src/ingest-cache.d.ts +25 -30
- package/dist/src/ingest-cache.js +108 -127
- package/dist/src/mind/articulation.d.ts +1 -5
- package/dist/src/mind/articulation.js +77 -112
- package/dist/src/mind/attention.d.ts +40 -108
- package/dist/src/mind/attention.js +754 -872
- package/dist/src/mind/canonical.d.ts +4 -19
- package/dist/src/mind/canonical.js +27 -31
- package/dist/src/mind/graph-search.d.ts +201 -225
- package/dist/src/mind/graph-search.js +742 -821
- package/dist/src/mind/index.d.ts +2 -10
- package/dist/src/mind/junction.d.ts +31 -58
- package/dist/src/mind/junction.js +172 -237
- package/dist/src/mind/learning.d.ts +16 -52
- package/dist/src/mind/learning.js +143 -165
- package/dist/src/mind/match.d.ts +20 -69
- package/dist/src/mind/match.js +259 -318
- package/dist/src/mind/mechanisms/alu.js +16 -16
- package/dist/src/mind/mechanisms/cast.d.ts +9 -13
- package/dist/src/mind/mechanisms/cast.js +363 -456
- package/dist/src/mind/mechanisms/confluence.d.ts +8 -12
- package/dist/src/mind/mechanisms/confluence.js +152 -183
- package/dist/src/mind/mechanisms/cover.d.ts +2 -8
- package/dist/src/mind/mechanisms/cover.js +148 -210
- package/dist/src/mind/mechanisms/extraction.d.ts +8 -34
- package/dist/src/mind/mechanisms/extraction.js +234 -288
- package/dist/src/mind/mechanisms/recall.d.ts +6 -10
- package/dist/src/mind/mechanisms/recall.js +141 -185
- package/dist/src/mind/mind.d.ts +194 -155
- package/dist/src/mind/mind.js +392 -289
- package/dist/src/mind/pipeline-mechanism.d.ts +112 -124
- package/dist/src/mind/pipeline-mechanism.js +161 -172
- package/dist/src/mind/pipeline.d.ts +4 -14
- package/dist/src/mind/pipeline.js +125 -189
- package/dist/src/mind/primitives.d.ts +20 -33
- package/dist/src/mind/primitives.js +124 -120
- package/dist/src/mind/rationale.d.ts +86 -98
- package/dist/src/mind/rationale.js +113 -121
- package/dist/src/mind/reasoning.d.ts +2 -13
- package/dist/src/mind/reasoning.js +129 -166
- package/dist/src/mind/recognition.d.ts +1 -4
- package/dist/src/mind/recognition.js +198 -210
- package/dist/src/mind/resonance.d.ts +5 -22
- package/dist/src/mind/resonance.js +0 -0
- package/dist/src/mind/trace.d.ts +6 -25
- package/dist/src/mind/trace.js +50 -58
- package/dist/src/mind/traverse.d.ts +29 -58
- package/dist/src/mind/traverse.js +344 -356
- package/dist/src/mind/types.d.ts +122 -127
- package/dist/src/mind/types.js +60 -69
- package/dist/src/rabitq-ivf/src/database.d.ts +113 -0
- package/dist/src/rabitq-ivf/src/database.js +201 -0
- package/dist/src/rabitq-ivf/src/index.d.ts +7 -0
- package/dist/src/{rabitq-hnsw → rabitq-ivf}/src/index.js +1 -3
- package/dist/src/rabitq-ivf/src/ivf.d.ts +200 -0
- package/dist/src/rabitq-ivf/src/ivf.js +1165 -0
- package/dist/src/rabitq-ivf/src/prng.d.ts +19 -0
- package/dist/src/rabitq-ivf/src/prng.js +36 -0
- package/dist/src/rabitq-ivf/src/rabitq.d.ts +95 -0
- package/dist/src/rabitq-ivf/src/rabitq.js +283 -0
- package/dist/src/sema.d.ts +9 -13
- package/dist/src/sema.js +26 -40
- package/dist/src/store-sqlite.d.ts +171 -166
- package/dist/src/store-sqlite.js +768 -662
- package/dist/src/store.d.ts +597 -630
- package/dist/src/store.js +1434 -1581
- package/dist/src/vec.d.ts +5 -9
- package/dist/src/vec.js +61 -73
- package/example/train_base.ts +33 -15
- package/index.html +65 -0
- package/package.json +1 -1
- package/src/alu/README.md +1 -1
- package/src/alu/src/index.ts +1 -1
- package/src/config.ts +19 -27
- package/src/geometry.ts +93 -1
- package/src/index.ts +6 -11
- package/src/mind/attention.ts +11 -6
- package/src/mind/mechanisms/recall.ts +29 -13
- package/src/mind/mind.ts +250 -19
- package/src/mind/primitives.ts +43 -6
- package/src/mind/recognition.ts +26 -8
- package/src/mind/traverse.ts +47 -0
- package/src/mind/types.ts +20 -21
- package/src/rabitq-ivf/README.md +56 -0
- package/src/rabitq-ivf/src/database.ts +276 -0
- package/src/{rabitq-hnsw → rabitq-ivf}/src/index.ts +2 -5
- package/src/rabitq-ivf/src/ivf.ts +1330 -0
- package/src/{rabitq-hnsw → rabitq-ivf}/src/prng.ts +1 -1
- package/src/store-sqlite.ts +204 -9
- package/src/store.ts +27 -34
- package/test/08-storage.test.mjs +3 -3
- package/test/13-conversation.test.mjs +190 -20
- package/test/14-scaling.test.mjs +2 -2
- package/test/35-ivf.test.mjs +263 -0
- package/test/36-bloom.test.mjs +123 -0
- package/dist/src/rabitq-hnsw/src/database.d.ts +0 -202
- package/dist/src/rabitq-hnsw/src/database.js +0 -405
- package/dist/src/rabitq-hnsw/src/heap.d.ts +0 -22
- package/dist/src/rabitq-hnsw/src/heap.js +0 -94
- package/dist/src/rabitq-hnsw/src/hnsw.d.ts +0 -125
- package/dist/src/rabitq-hnsw/src/hnsw.js +0 -500
- package/dist/src/rabitq-hnsw/src/index.d.ts +0 -15
- package/dist/src/rabitq-hnsw/src/prng.d.ts +0 -19
- package/dist/src/rabitq-hnsw/src/prng.js +0 -38
- package/dist/src/rabitq-hnsw/src/rabitq.d.ts +0 -95
- package/dist/src/rabitq-hnsw/src/rabitq.js +0 -299
- package/dist/src/rabitq-hnsw/src/store.d.ts +0 -162
- package/dist/src/rabitq-hnsw/src/store.js +0 -916
- package/dist/src/rabitq-hnsw/test/hnsw.test.d.ts +0 -1
- package/dist/src/rabitq-hnsw/test/hnsw.test.js +0 -1197
- package/src/rabitq-hnsw/README.md +0 -303
- package/src/rabitq-hnsw/src/database.ts +0 -492
- package/src/rabitq-hnsw/src/heap.ts +0 -90
- package/src/rabitq-hnsw/src/hnsw.ts +0 -514
- package/src/rabitq-hnsw/src/store.ts +0 -994
- package/src/rabitq-hnsw/test/hnsw.test.ts +0 -1213
- /package/src/{rabitq-hnsw → rabitq-ivf}/src/rabitq.ts +0 -0
|
@@ -25,30 +25,30 @@
|
|
|
25
25
|
// functions, composed from the same scalar primitives, and tested directly.
|
|
26
26
|
// `linsolve` is Gaussian elimination — structured arithmetic, not a new
|
|
27
27
|
// primitive.
|
|
28
|
-
import { asInt, asReal, bit, int, joinDomain, real } from "./value.js";
|
|
28
|
+
import { asInt, asReal, bit, int, joinDomain, real, } from "./value.js";
|
|
29
29
|
/** Reduce numeric operands in their join domain: exact bigint when all are
|
|
30
30
|
* bit/int, native double once any is real. `bigOp` and `realOp` are the same
|
|
31
31
|
* fold expressed in each carrier. */
|
|
32
32
|
function reduceNumeric(args, identityBig, bigOp, realOp) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const d = joinDomain(args);
|
|
34
|
+
if (d === "real") {
|
|
35
|
+
let acc = Number(identityBig);
|
|
36
|
+
let first = true;
|
|
37
|
+
for (const a of args) {
|
|
38
|
+
const x = asReal(a);
|
|
39
|
+
acc = first ? x : realOp(acc, x);
|
|
40
|
+
first = false;
|
|
41
|
+
}
|
|
42
|
+
return real(acc);
|
|
43
|
+
}
|
|
44
|
+
let acc = identityBig;
|
|
36
45
|
let first = true;
|
|
37
46
|
for (const a of args) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
const n = asInt(a);
|
|
48
|
+
acc = first ? n : bigOp(acc, n);
|
|
49
|
+
first = false;
|
|
41
50
|
}
|
|
42
|
-
return
|
|
43
|
-
}
|
|
44
|
-
let acc = identityBig;
|
|
45
|
-
let first = true;
|
|
46
|
-
for (const a of args) {
|
|
47
|
-
const n = asInt(a);
|
|
48
|
-
acc = first ? n : bigOp(acc, n);
|
|
49
|
-
first = false;
|
|
50
|
-
}
|
|
51
|
-
return int(acc);
|
|
51
|
+
return int(acc);
|
|
52
52
|
}
|
|
53
53
|
// The infix binding tiers of arithmetic notation, loosest to tightest. These
|
|
54
54
|
// are declared ONCE, here, next to the ops they describe; the expression
|
|
@@ -61,294 +61,204 @@ const MULTIPLICATIVE = { precedence: 2 };
|
|
|
61
61
|
const EXPONENT = { precedence: 3, rightAssoc: true };
|
|
62
62
|
/** Register the arithmetic layer into `r`. */
|
|
63
63
|
export function registerArith(r) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
],
|
|
88
|
-
|
|
89
|
-
{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
["
|
|
103
|
-
(args) =>
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
(args, ctx) =>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
2,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
2,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
"
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
// min / max select on the comparison — the control flow layer 1 provides.
|
|
193
|
-
r.derive(
|
|
194
|
-
"min",
|
|
195
|
-
2,
|
|
196
|
-
["min"],
|
|
197
|
-
(args, ctx) => cmpSign(args, ctx) <= 0n ? args[0] : args[1],
|
|
198
|
-
);
|
|
199
|
-
r.derive(
|
|
200
|
-
"max",
|
|
201
|
-
2,
|
|
202
|
-
["max"],
|
|
203
|
-
(args, ctx) => cmpSign(args, ctx) >= 0n ? args[0] : args[1],
|
|
204
|
-
);
|
|
205
|
-
// ── derived: power ───────────────────────────────────────────────────────
|
|
206
|
-
// Integer exponent → repeated multiply (exact); non-integer or real → fall to
|
|
207
|
-
// the limit layer's exp(e·log b) when it is registered.
|
|
208
|
-
r.derive("power", 2, ["^", "**", "pow", "power"], (args, ctx) => {
|
|
209
|
-
const base = args[0];
|
|
210
|
-
const e = args[1];
|
|
211
|
-
// An INTEGER-VALUED exponent → repeated multiply (exact), even if it arrived
|
|
212
|
-
// as a real that happens to be whole (a derived call may hand a real 2.0).
|
|
213
|
-
// This keeps b^2 exact and avoids exp(e·ln b), which is approximate and
|
|
214
|
-
// undefined for a negative base (ln(−3) = NaN). Only a genuinely fractional
|
|
215
|
-
// exponent falls to the limit layer.
|
|
216
|
-
const eInt = e.domain !== "real"
|
|
217
|
-
? asInt(e)
|
|
218
|
-
: Number.isInteger(e.x)
|
|
219
|
-
? BigInt(e.x)
|
|
220
|
-
: null;
|
|
221
|
-
if (eInt !== null) {
|
|
222
|
-
let n = eInt;
|
|
223
|
-
const neg = n < 0n;
|
|
224
|
-
if (neg) {
|
|
225
|
-
n = -n;
|
|
226
|
-
}
|
|
227
|
-
let acc = int(1n);
|
|
228
|
-
for (let i = 0n; i < n; i++) {
|
|
229
|
-
acc = ctx.apply("multiply", [acc, base]);
|
|
230
|
-
}
|
|
231
|
-
return neg ? ctx.apply("reciprocal", [acc]) : acc;
|
|
232
|
-
}
|
|
233
|
-
// Fractional exponent: b^e = exp(e·ln b), needing the limit layer.
|
|
234
|
-
if (ctx.has("exp") && ctx.has("log")) {
|
|
235
|
-
return ctx.apply("exp", [
|
|
236
|
-
ctx.apply("multiply", [e, ctx.apply("log", [base])]),
|
|
237
|
-
]);
|
|
238
|
-
}
|
|
239
|
-
return real(Math.pow(asReal(base), asReal(e)));
|
|
240
|
-
}, { infix: EXPONENT });
|
|
241
|
-
// gcd via Euclid (mod) — number theory standing on the integer primitives.
|
|
242
|
-
r.derive("gcd", 2, ["gcd"], (args, ctx) => {
|
|
243
|
-
let a = asInt(args[0]);
|
|
244
|
-
let b = asInt(args[1]);
|
|
245
|
-
a = a < 0n ? -a : a;
|
|
246
|
-
b = b < 0n ? -b : b;
|
|
247
|
-
while (b !== 0n) {
|
|
248
|
-
const t = asInt(ctx.apply("mod", [int(a), int(b)]));
|
|
249
|
-
a = b;
|
|
250
|
-
b = t < 0n ? -t : t;
|
|
251
|
-
}
|
|
252
|
-
return int(a);
|
|
253
|
-
});
|
|
254
|
-
// ── polymorphic inverse (the bridge to the symbol domain) ────────────────
|
|
255
|
-
// The additive inverse of a NUMBER is its negation; the inverse of a SYMBOL is
|
|
256
|
-
// its RESONANT OPPOSITE — found by the host's resonance and pre-resolved into
|
|
257
|
-
// ctx.resonance (see resonance.ts). One op, dispatched on the operand's
|
|
258
|
-
// domain: this is "inverse of 3 is −3, inverse of <a learned form> is its
|
|
259
|
-
// opposite", in any modality. A bit inverts as logical not.
|
|
260
|
-
r.derive("inverse", 1, ["inverse", "opposite", "invert"], (args, ctx) => {
|
|
261
|
-
const v = args[0];
|
|
262
|
-
if (v.domain === "symbol") {
|
|
263
|
-
const opp = ctx.resonance.opposite(v.bytes);
|
|
264
|
-
// No known opposite → leave the form unchanged rather than fabricate one
|
|
265
|
-
// (faithfulness: ALU never invents meaning resonance did not supply).
|
|
266
|
-
return opp ? { domain: "symbol", bytes: opp } : v;
|
|
267
|
-
}
|
|
268
|
-
if (v.domain === "bit") {
|
|
269
|
-
return ctx.apply("not", [v]);
|
|
270
|
-
}
|
|
271
|
-
return ctx.apply("negate", [v]);
|
|
272
|
-
});
|
|
273
|
-
// reciprocal already registered as the multiplicative inverse primitive.
|
|
64
|
+
// ── identities ──────────────────────────────────────────────────────────
|
|
65
|
+
r.prim("zero", 0, ["0"], () => int(0n));
|
|
66
|
+
r.prim("one", 0, ["1"], () => int(1n));
|
|
67
|
+
// ── primitives ──────────────────────────────────────────────────────────
|
|
68
|
+
// add / multiply are variadic folds (so "sum"/"product" of many is one call);
|
|
69
|
+
// the infix path calls them with exactly two operands.
|
|
70
|
+
r.prim("add", "variadic", ["+", "plus", "sum", "add", "total"], (args) => reduceNumeric(args, 0n, (a, b) => a + b, (a, b) => a + b), { infix: ADDITIVE });
|
|
71
|
+
r.prim("multiply", "variadic", [
|
|
72
|
+
"*",
|
|
73
|
+
"×",
|
|
74
|
+
"·",
|
|
75
|
+
"times",
|
|
76
|
+
"multiply",
|
|
77
|
+
"product",
|
|
78
|
+
], (args) => reduceNumeric(args, 1n, (a, b) => a * b, (a, b) => a * b), {
|
|
79
|
+
infix: MULTIPLICATIVE,
|
|
80
|
+
});
|
|
81
|
+
r.prim("negate", 1, ["-", "negate", "neg"], (args) => {
|
|
82
|
+
const v = args[0];
|
|
83
|
+
return v.domain === "real" ? real(-v.x) : int(-asInt(v));
|
|
84
|
+
});
|
|
85
|
+
// reciprocal lives in the reals: 1/2 = 0.5, so it lifts to a double (an int
|
|
86
|
+
// result like 1/1 still formats cleanly through the codec).
|
|
87
|
+
r.prim("reciprocal", 1, ["reciprocal", "recip"], (args) => real(1 / asReal(args[0])));
|
|
88
|
+
// sign ∈ {−1, 0, +1}, returned exact (int) so comparisons are exact.
|
|
89
|
+
r.prim("sign", 1, ["sign", "sgn"], (args) => {
|
|
90
|
+
const v = args[0];
|
|
91
|
+
if (v.domain === "real")
|
|
92
|
+
return int(v.x > 0 ? 1n : v.x < 0 ? -1n : 0n);
|
|
93
|
+
const n = asInt(v);
|
|
94
|
+
return int(n > 0n ? 1n : n < 0n ? -1n : 0n);
|
|
95
|
+
});
|
|
96
|
+
// floor / mod — the optional integer-number-theory primitives.
|
|
97
|
+
r.prim("floor", 1, ["floor"], (args) => {
|
|
98
|
+
const v = args[0];
|
|
99
|
+
return v.domain === "real" ? int(BigInt(Math.floor(v.x))) : int(asInt(v));
|
|
100
|
+
});
|
|
101
|
+
// ── derived: the field ─────────────────────────────────────────────────
|
|
102
|
+
r.derive("subtract", 2, ["-", "minus", "subtract", "difference", "less"], (args, ctx) => ctx.apply("add", [args[0], ctx.apply("negate", [args[1]])]), { infix: ADDITIVE });
|
|
103
|
+
r.derive("divide", 2, ["/", "÷", "divide", "over"], (args, ctx) => ctx.apply("multiply", [args[0], ctx.apply("reciprocal", [args[1]])]), { infix: MULTIPLICATIVE });
|
|
104
|
+
// Euclidean-style remainder. Exact for ints; native % for reals.
|
|
105
|
+
r.derive("mod", 2, ["mod", "%", "modulo"], (args, ctx) => {
|
|
106
|
+
void ctx;
|
|
107
|
+
const d = joinDomain(args);
|
|
108
|
+
if (d === "real")
|
|
109
|
+
return real(asReal(args[0]) % asReal(args[1]));
|
|
110
|
+
return int(asInt(args[0]) % asInt(args[1]));
|
|
111
|
+
}, { infix: MULTIPLICATIVE });
|
|
112
|
+
// ── derived: order (every comparison = sign ∘ subtract → a truth bit) ────
|
|
113
|
+
const cmpSign = (args, ctx) => asInt(ctx.apply("sign", [ctx.apply("subtract", [args[0], args[1]])]));
|
|
114
|
+
r.derive("eq", 2, ["=", "==", "equals", "eq"], (args, ctx) => bit(cmpSign(args, ctx) === 0n ? 1 : 0));
|
|
115
|
+
r.derive("ne", 2, ["!=", "≠", "ne"], (args, ctx) => bit(cmpSign(args, ctx) !== 0n ? 1 : 0));
|
|
116
|
+
r.derive("lt", 2, ["<", "lt"], (args, ctx) => bit(cmpSign(args, ctx) < 0n ? 1 : 0));
|
|
117
|
+
r.derive("le", 2, ["<=", "≤", "le"], (args, ctx) => bit(cmpSign(args, ctx) <= 0n ? 1 : 0));
|
|
118
|
+
r.derive("gt", 2, [">", "gt"], (args, ctx) => bit(cmpSign(args, ctx) > 0n ? 1 : 0));
|
|
119
|
+
r.derive("ge", 2, [">=", "≥", "ge"], (args, ctx) => bit(cmpSign(args, ctx) >= 0n ? 1 : 0));
|
|
120
|
+
// ── derived: magnitude / extremes ────────────────────────────────────────
|
|
121
|
+
// abs(x) = sign(x)·x — branch-free.
|
|
122
|
+
r.derive("abs", 1, ["abs", "|x|"], (args, ctx) => ctx.apply("multiply", [ctx.apply("sign", [args[0]]), args[0]]));
|
|
123
|
+
// min / max select on the comparison — the control flow layer 1 provides.
|
|
124
|
+
r.derive("min", 2, ["min"], (args, ctx) => cmpSign(args, ctx) <= 0n ? args[0] : args[1]);
|
|
125
|
+
r.derive("max", 2, ["max"], (args, ctx) => cmpSign(args, ctx) >= 0n ? args[0] : args[1]);
|
|
126
|
+
// ── derived: power ───────────────────────────────────────────────────────
|
|
127
|
+
// Integer exponent → repeated multiply (exact); non-integer or real → fall to
|
|
128
|
+
// the limit layer's exp(e·log b) when it is registered.
|
|
129
|
+
r.derive("power", 2, ["^", "**", "pow", "power"], (args, ctx) => {
|
|
130
|
+
const base = args[0];
|
|
131
|
+
const e = args[1];
|
|
132
|
+
// An INTEGER-VALUED exponent → repeated multiply (exact), even if it arrived
|
|
133
|
+
// as a real that happens to be whole (a derived call may hand a real 2.0).
|
|
134
|
+
// This keeps b^2 exact and avoids exp(e·ln b), which is approximate and
|
|
135
|
+
// undefined for a negative base (ln(−3) = NaN). Only a genuinely fractional
|
|
136
|
+
// exponent falls to the limit layer.
|
|
137
|
+
const eInt = e.domain !== "real"
|
|
138
|
+
? asInt(e)
|
|
139
|
+
: Number.isInteger(e.x)
|
|
140
|
+
? BigInt(e.x)
|
|
141
|
+
: null;
|
|
142
|
+
if (eInt !== null) {
|
|
143
|
+
let n = eInt;
|
|
144
|
+
const neg = n < 0n;
|
|
145
|
+
if (neg)
|
|
146
|
+
n = -n;
|
|
147
|
+
let acc = int(1n);
|
|
148
|
+
for (let i = 0n; i < n; i++)
|
|
149
|
+
acc = ctx.apply("multiply", [acc, base]);
|
|
150
|
+
return neg ? ctx.apply("reciprocal", [acc]) : acc;
|
|
151
|
+
}
|
|
152
|
+
// Fractional exponent: b^e = exp(e·ln b), needing the limit layer.
|
|
153
|
+
if (ctx.has("exp") && ctx.has("log")) {
|
|
154
|
+
return ctx.apply("exp", [
|
|
155
|
+
ctx.apply("multiply", [e, ctx.apply("log", [base])]),
|
|
156
|
+
]);
|
|
157
|
+
}
|
|
158
|
+
return real(Math.pow(asReal(base), asReal(e)));
|
|
159
|
+
}, { infix: EXPONENT });
|
|
160
|
+
// gcd via Euclid (mod) — number theory standing on the integer primitives.
|
|
161
|
+
r.derive("gcd", 2, ["gcd"], (args, ctx) => {
|
|
162
|
+
let a = asInt(args[0]);
|
|
163
|
+
let b = asInt(args[1]);
|
|
164
|
+
a = a < 0n ? -a : a;
|
|
165
|
+
b = b < 0n ? -b : b;
|
|
166
|
+
while (b !== 0n) {
|
|
167
|
+
const t = asInt(ctx.apply("mod", [int(a), int(b)]));
|
|
168
|
+
a = b;
|
|
169
|
+
b = t < 0n ? -t : t;
|
|
170
|
+
}
|
|
171
|
+
return int(a);
|
|
172
|
+
});
|
|
173
|
+
// ── polymorphic inverse (the bridge to the symbol domain) ────────────────
|
|
174
|
+
// The additive inverse of a NUMBER is its negation; the inverse of a SYMBOL is
|
|
175
|
+
// its RESONANT OPPOSITE — found by the host's resonance and pre-resolved into
|
|
176
|
+
// ctx.resonance (see resonance.ts). One op, dispatched on the operand's
|
|
177
|
+
// domain: this is "inverse of 3 is −3, inverse of <a learned form> is its
|
|
178
|
+
// opposite", in any modality. A bit inverts as logical not.
|
|
179
|
+
r.derive("inverse", 1, ["inverse", "opposite", "invert"], (args, ctx) => {
|
|
180
|
+
const v = args[0];
|
|
181
|
+
if (v.domain === "symbol") {
|
|
182
|
+
const opp = ctx.resonance.opposite(v.bytes);
|
|
183
|
+
// No known opposite → leave the form unchanged rather than fabricate one
|
|
184
|
+
// (faithfulness: ALU never invents meaning resonance did not supply).
|
|
185
|
+
return opp ? { domain: "symbol", bytes: opp } : v;
|
|
186
|
+
}
|
|
187
|
+
if (v.domain === "bit")
|
|
188
|
+
return ctx.apply("not", [v]);
|
|
189
|
+
return ctx.apply("negate", [v]);
|
|
190
|
+
});
|
|
191
|
+
// reciprocal already registered as the multiplicative inverse primitive.
|
|
274
192
|
}
|
|
275
193
|
// ── exported array routines (derivations whose natural shape is arrays) ──────
|
|
276
194
|
/** Horner evaluation of a polynomial whose coefficients run constant-first
|
|
277
195
|
* (`coeffs[0]` is the constant term). Pure arithmetic over add/multiply. */
|
|
278
196
|
export function polyEval(coeffs, x) {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
return acc;
|
|
197
|
+
let acc = 0;
|
|
198
|
+
for (let i = coeffs.length - 1; i >= 0; i--)
|
|
199
|
+
acc = acc * x + coeffs[i];
|
|
200
|
+
return acc;
|
|
284
201
|
}
|
|
285
202
|
/** Dot product of two equal-length vectors — a fold of add over multiply. */
|
|
286
203
|
export function dot(a, b) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
s
|
|
293
|
-
}
|
|
294
|
-
return s;
|
|
204
|
+
if (a.length !== b.length)
|
|
205
|
+
throw new Error("dot: length mismatch");
|
|
206
|
+
let s = 0;
|
|
207
|
+
for (let i = 0; i < a.length; i++)
|
|
208
|
+
s += a[i] * b[i];
|
|
209
|
+
return s;
|
|
295
210
|
}
|
|
296
211
|
/** Matrix · vector. */
|
|
297
212
|
export function matVec(m, v) {
|
|
298
|
-
|
|
213
|
+
return m.map((row) => dot(row, v));
|
|
299
214
|
}
|
|
300
215
|
/** Matrix · matrix. */
|
|
301
216
|
export function matMul(a, b) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
217
|
+
const n = a.length;
|
|
218
|
+
const k = b.length;
|
|
219
|
+
const p = b[0].length;
|
|
220
|
+
const out = Array.from({ length: n }, () => new Array(p).fill(0));
|
|
221
|
+
for (let i = 0; i < n; i++) {
|
|
222
|
+
for (let j = 0; j < p; j++) {
|
|
223
|
+
let s = 0;
|
|
224
|
+
for (let t = 0; t < k; t++)
|
|
225
|
+
s += a[i][t] * b[t][j];
|
|
226
|
+
out[i][j] = s;
|
|
227
|
+
}
|
|
313
228
|
}
|
|
314
|
-
|
|
315
|
-
return out;
|
|
229
|
+
return out;
|
|
316
230
|
}
|
|
317
231
|
/** Solve A·x = b by Gaussian elimination with partial pivoting — structured
|
|
318
232
|
* arithmetic (add / multiply / divide / compare for the pivot), not a new
|
|
319
233
|
* primitive. Returns x, or null if A is singular to tolerance `tol`. */
|
|
320
234
|
export function linsolve(A, b, tol = 1e-12) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
M[r][c] -= f * M[col][c];
|
|
341
|
-
}
|
|
235
|
+
const n = A.length;
|
|
236
|
+
// Work on an augmented copy so the inputs are untouched.
|
|
237
|
+
const M = A.map((row, i) => [...row, b[i]]);
|
|
238
|
+
for (let col = 0; col < n; col++) {
|
|
239
|
+
// Partial pivot: the row with the largest |value| in this column.
|
|
240
|
+
let piv = col;
|
|
241
|
+
for (let r = col + 1; r < n; r++) {
|
|
242
|
+
if (Math.abs(M[r][col]) > Math.abs(M[piv][col]))
|
|
243
|
+
piv = r;
|
|
244
|
+
}
|
|
245
|
+
if (Math.abs(M[piv][col]) < tol)
|
|
246
|
+
return null; // singular
|
|
247
|
+
[M[col], M[piv]] = [M[piv], M[col]];
|
|
248
|
+
// Eliminate below.
|
|
249
|
+
for (let r = col + 1; r < n; r++) {
|
|
250
|
+
const f = M[r][col] / M[col][col];
|
|
251
|
+
for (let c = col; c <= n; c++)
|
|
252
|
+
M[r][c] -= f * M[col][c];
|
|
253
|
+
}
|
|
342
254
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
255
|
+
// Back-substitute.
|
|
256
|
+
const x = new Array(n).fill(0);
|
|
257
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
258
|
+
let s = M[i][n];
|
|
259
|
+
for (let j = i + 1; j < n; j++)
|
|
260
|
+
s -= M[i][j] * x[j];
|
|
261
|
+
x[i] = s / M[i][i];
|
|
350
262
|
}
|
|
351
|
-
x
|
|
352
|
-
}
|
|
353
|
-
return x;
|
|
263
|
+
return x;
|
|
354
264
|
}
|
|
@@ -12,11 +12,7 @@ export declare function mulBits(ctx: OpContext, a: bigint, b: bigint): bigint;
|
|
|
12
12
|
export declare function signBits(ctx: OpContext, a: bigint): bigint;
|
|
13
13
|
/** Compare via sign(subtract): −1 if a<b, 0 if a=b, +1 if a>b, where subtract is
|
|
14
14
|
* add ∘ negate — so comparison is structured arithmetic, not a new primitive. */
|
|
15
|
-
export declare function compareBits(
|
|
16
|
-
ctx: OpContext,
|
|
17
|
-
a: bigint,
|
|
18
|
-
b: bigint,
|
|
19
|
-
): bigint;
|
|
15
|
+
export declare function compareBits(ctx: OpContext, a: bigint, b: bigint): bigint;
|
|
20
16
|
/** Register the bit-bootstrap ops (int domain) into `r`. They have no surface
|
|
21
17
|
* forms — they are an internal exhibit, exercised by the tests and by anyone
|
|
22
18
|
* who wants to walk the nand→arithmetic chain, not matched from a query. */
|