@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
@@ -46,8 +46,8 @@ export const int = (n) => ({ domain: "int", n });
46
46
  export const real = (x) => ({ domain: "real", x });
47
47
  /** A symbolic value: an opaque byte span of any modality (see module note). */
48
48
  export const symbol = (bytes) => ({
49
- domain: "symbol",
50
- bytes,
49
+ domain: "symbol",
50
+ bytes,
51
51
  });
52
52
  /** An n-dimensional value: an ordered list of element values (each any domain,
53
53
  * including a nested nd). See the module note on nd. */
@@ -57,11 +57,11 @@ export const tagOf = (v) => v.domain;
57
57
  /** Whether a value is a numeric SCALAR (bit, int, or real) — an nd is not, even
58
58
  * if every element is numeric (it is a container; reduce it to a scalar). */
59
59
  export function isNumeric(v) {
60
- return v.domain === "bit" || v.domain === "int" || v.domain === "real";
60
+ return v.domain === "bit" || v.domain === "int" || v.domain === "real";
61
61
  }
62
62
  /** Whether a value is the n-dimensional container. */
63
63
  export function isNd(v) {
64
- return v.domain === "nd";
64
+ return v.domain === "nd";
65
65
  }
66
66
  /** Collect, into `out`, every SYMBOL byte span reachable inside a value — itself
67
67
  * when it is a symbol, or each element recursively when it is an nd. These are
@@ -69,12 +69,13 @@ export function isNd(v) {
69
69
  * argument names) the host pre-resolves before a computation; numbers carry no
70
70
  * meaning to resolve, so they are skipped. */
71
71
  export function symbolSpans(v, out) {
72
- if (v.domain === "symbol")
73
- out.push(v.bytes);
74
- else if (isNd(v)) {
75
- for (const e of v.items)
76
- symbolSpans(e, out);
72
+ if (v.domain === "symbol") {
73
+ out.push(v.bytes);
74
+ } else if (isNd(v)) {
75
+ for (const e of v.items) {
76
+ symbolSpans(e, out);
77
77
  }
78
+ }
78
79
  }
79
80
  // ── coercions (the functor's object map between domains) ────────────────────
80
81
  /** A value as a JS number — bit→0|1, int→Number, real as-is. Throws on a
@@ -82,103 +83,108 @@ export function symbolSpans(v, out) {
82
83
  * caller (or the graph adapter's try/catch) should surface, never silently
83
84
  * coerce to NaN. */
84
85
  export function asReal(v) {
85
- switch (v.domain) {
86
- case "bit":
87
- return v.b;
88
- case "int":
89
- return Number(v.n);
90
- case "real":
91
- return v.x;
92
- case "symbol":
93
- throw new TypeError("asReal: a symbol value has no numeric reading");
94
- case "nd":
95
- // An nd has no scalar reading: a scalar primitive never sees one, because
96
- // broadcast (operation.ts) lifts it element-wise first. Reaching here
97
- // means a structural op was mis-called on a list as if it were a scalar.
98
- throw new TypeError("asReal: an nd value has no scalar numeric reading");
99
- }
86
+ switch (v.domain) {
87
+ case "bit":
88
+ return v.b;
89
+ case "int":
90
+ return Number(v.n);
91
+ case "real":
92
+ return v.x;
93
+ case "symbol":
94
+ throw new TypeError("asReal: a symbol value has no numeric reading");
95
+ case "nd":
96
+ // An nd has no scalar reading: a scalar primitive never sees one, because
97
+ // broadcast (operation.ts) lifts it element-wise first. Reaching here
98
+ // means a structural op was mis-called on a list as if it were a scalar.
99
+ throw new TypeError("asReal: an nd value has no scalar numeric reading");
100
+ }
100
101
  }
101
102
  /** A value as an exact bigint — real is truncated toward zero (a real that is
102
103
  * not integral loses its fraction; callers wanting exactness keep it int). */
103
104
  export function asInt(v) {
104
- switch (v.domain) {
105
- case "bit":
106
- return BigInt(v.b);
107
- case "int":
108
- return v.n;
109
- case "real":
110
- return BigInt(Math.trunc(v.x));
111
- case "symbol":
112
- throw new TypeError("asInt: a symbol value has no integer reading");
113
- case "nd":
114
- throw new TypeError("asInt: an nd value has no scalar integer reading");
115
- }
105
+ switch (v.domain) {
106
+ case "bit":
107
+ return BigInt(v.b);
108
+ case "int":
109
+ return v.n;
110
+ case "real":
111
+ return BigInt(Math.trunc(v.x));
112
+ case "symbol":
113
+ throw new TypeError("asInt: a symbol value has no integer reading");
114
+ case "nd":
115
+ throw new TypeError("asInt: an nd value has no scalar integer reading");
116
+ }
116
117
  }
117
118
  /** A value as a logic bit — nonzero numbers read as 1, zero as 0. Throws on a
118
119
  * symbol (an opaque form is not a truth value). */
119
120
  export function asBit(v) {
120
- switch (v.domain) {
121
- case "bit":
122
- return v.b;
123
- case "int":
124
- return v.n === 0n ? 0 : 1;
125
- case "real":
126
- return v.x === 0 ? 0 : 1;
127
- case "symbol":
128
- throw new TypeError("asBit: a symbol value is not a truth value");
129
- case "nd":
130
- throw new TypeError("asBit: an nd value is not a scalar truth value");
131
- }
121
+ switch (v.domain) {
122
+ case "bit":
123
+ return v.b;
124
+ case "int":
125
+ return v.n === 0n ? 0 : 1;
126
+ case "real":
127
+ return v.x === 0 ? 0 : 1;
128
+ case "symbol":
129
+ throw new TypeError("asBit: a symbol value is not a truth value");
130
+ case "nd":
131
+ throw new TypeError("asBit: an nd value is not a scalar truth value");
132
+ }
132
133
  }
133
134
  /** Promote a value into a target numeric domain (bit ⊂ int ⊂ real). Used when
134
135
  * a mixed-domain expression must agree on one domain before a primitive runs —
135
136
  * the rule is the natural lattice: any real operand pulls the whole expression
136
137
  * to real, otherwise any int pulls it to int, otherwise bit. */
137
138
  export function coerce(v, domain) {
138
- if (v.domain === domain)
139
- return v;
140
- switch (domain) {
141
- case "bit":
142
- return bit(asBit(v));
143
- case "int":
144
- return int(asInt(v));
145
- case "real":
146
- return real(asReal(v));
147
- }
139
+ if (v.domain === domain) {
140
+ return v;
141
+ }
142
+ switch (domain) {
143
+ case "bit":
144
+ return bit(asBit(v));
145
+ case "int":
146
+ return int(asInt(v));
147
+ case "real":
148
+ return real(asReal(v));
149
+ }
148
150
  }
149
151
  /** The common numeric domain of a list of operands, by the bit ⊂ int ⊂ real
150
152
  * lattice: real if any operand is real, else int if any is int, else bit.
151
153
  * Throws if any operand is a symbol. This is how a polymorphic arithmetic op
152
154
  * decides whether to take the exact bigint path or the native-double path. */
153
155
  export function joinDomain(args) {
154
- let d = "bit";
155
- for (const a of args) {
156
- if (a.domain === "symbol") {
157
- throw new TypeError("joinDomain: cannot join a symbol value numerically");
158
- }
159
- if (a.domain === "nd") {
160
- throw new TypeError("joinDomain: cannot join an nd value numerically");
161
- }
162
- if (a.domain === "real")
163
- return "real";
164
- if (a.domain === "int" && d === "bit")
165
- d = "int";
156
+ let d = "bit";
157
+ for (const a of args) {
158
+ if (a.domain === "symbol") {
159
+ throw new TypeError("joinDomain: cannot join a symbol value numerically");
160
+ }
161
+ if (a.domain === "nd") {
162
+ throw new TypeError("joinDomain: cannot join an nd value numerically");
166
163
  }
167
- return d;
164
+ if (a.domain === "real") {
165
+ return "real";
166
+ }
167
+ if (a.domain === "int" && d === "bit") {
168
+ d = "int";
169
+ }
170
+ }
171
+ return d;
168
172
  }
169
173
  const ASCII = {
170
- decode: (b) => {
171
- let s = "";
172
- for (let i = 0; i < b.length; i++)
173
- s += String.fromCharCode(b[i]);
174
- return s;
175
- },
176
- encode: (s) => {
177
- const out = new Uint8Array(s.length);
178
- for (let i = 0; i < s.length; i++)
179
- out[i] = s.charCodeAt(i) & 0xff;
180
- return out;
181
- },
174
+ decode: (b) => {
175
+ let s = "";
176
+ for (let i = 0; i < b.length; i++) {
177
+ s += String.fromCharCode(b[i]);
178
+ }
179
+ return s;
180
+ },
181
+ encode: (s) => {
182
+ const out = new Uint8Array(s.length);
183
+ for (let i = 0; i < s.length; i++) {
184
+ out[i] = s.charCodeAt(i) & 0xff;
185
+ }
186
+ return out;
187
+ },
182
188
  };
183
189
  /** A decimal numeral, sign, optional fraction, optional exponent — the syntax
184
190
  * {@link parseScalar} accepts as a number. Anything else is a symbol. */
@@ -186,38 +192,38 @@ const NUMERAL = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
186
192
  /** Concatenate byte arrays — used to build an nd literal's encoding without
187
193
  * routing a (possibly non-ASCII, multimodal) symbol's bytes through a string. */
188
194
  function concatBytes(arrs) {
189
- let len = 0;
190
- for (const a of arrs)
191
- len += a.length;
192
- const out = new Uint8Array(len);
193
- let o = 0;
194
- for (const a of arrs) {
195
- out.set(a, o);
196
- o += a.length;
197
- }
198
- return out;
195
+ let len = 0;
196
+ for (const a of arrs) {
197
+ len += a.length;
198
+ }
199
+ const out = new Uint8Array(len);
200
+ let o = 0;
201
+ for (const a of arrs) {
202
+ out.set(a, o);
203
+ o += a.length;
204
+ }
205
+ return out;
199
206
  }
200
207
  /** Parse a SCALAR span: a clean integer numeral → exact int, a fractional/
201
208
  * exponent numeral → real, anything else → a symbol carrying `bytes` verbatim.
202
209
  * Strict, so it never hijacks a form that merely begins with a digit. */
203
210
  function parseScalar(bytes, s) {
204
- if (s.length > 0 && NUMERAL.test(s)) {
205
- if (/[.eE]/.test(s)) {
206
- const x = Number(s);
207
- if (Number.isFinite(x))
208
- return real(x);
209
- }
210
- else {
211
- // A clean integer: strip a leading '+' that BigInt rejects.
212
- try {
213
- return int(BigInt(s[0] === "+" ? s.slice(1) : s));
214
- }
215
- catch {
216
- /* fall through to symbol */
217
- }
218
- }
211
+ if (s.length > 0 && NUMERAL.test(s)) {
212
+ if (/[.eE]/.test(s)) {
213
+ const x = Number(s);
214
+ if (Number.isFinite(x)) {
215
+ return real(x);
216
+ }
217
+ } else {
218
+ // A clean integer: strip a leading '+' that BigInt rejects.
219
+ try {
220
+ return int(BigInt(s[0] === "+" ? s.slice(1) : s));
221
+ } catch {
222
+ /* fall through to symbol */
223
+ }
219
224
  }
220
- return symbol(bytes);
225
+ }
226
+ return symbol(bytes);
221
227
  }
222
228
  /** Parse a byte span into a SCALAR value: a clean integer numeral → exact int, a
223
229
  * fractional/exponent numeral → real, anything else → a symbol carrying its
@@ -235,21 +241,24 @@ function parseScalar(bytes, s) {
235
241
  * Numerals are ASCII by construction; for any other byte content the bytes are
236
242
  * preserved opaquely, so a symbol of any modality round-trips untouched. */
237
243
  export function parseValue(bytes) {
238
- return parseScalar(bytes, ASCII.decode(bytes));
244
+ return parseScalar(bytes, ASCII.decode(bytes));
239
245
  }
240
246
  /** Canonically format a real as a decimal string: round to `precision` places,
241
247
  * then trim trailing zeros (and a bare trailing point), normalising -0 to 0.
242
248
  * Determinism here is load-bearing — the search keys an output span by its
243
249
  * bytes, so two derivations of the same number MUST spell it identically. */
244
250
  export function formatReal(x, precision) {
245
- if (!Number.isFinite(x))
246
- return String(x); // "Infinity" / "NaN" / "-Infinity"
247
- let s = x.toFixed(precision);
248
- if (s.indexOf(".") >= 0)
249
- s = s.replace(/\.?0+$/, "");
250
- if (s === "-0" || s === "")
251
- s = "0";
252
- return s;
251
+ if (!Number.isFinite(x)) {
252
+ return String(x); // "Infinity" / "NaN" / "-Infinity"
253
+ }
254
+ let s = x.toFixed(precision);
255
+ if (s.indexOf(".") >= 0) {
256
+ s = s.replace(/\.?0+$/, "");
257
+ }
258
+ if (s === "-0" || s === "") {
259
+ s = "0";
260
+ }
261
+ return s;
253
262
  }
254
263
  /** The default codec: integers as exact decimals, reals canonically formatted,
255
264
  * bits as "0"/"1", symbols as their own bytes (verbatim, any modality), and an
@@ -264,37 +273,38 @@ export function formatReal(x, precision) {
264
273
  * bracket literal decodes back to an opaque symbol. Reading list STRUCTURE from
265
274
  * bytes is layered one level up, in {@link "./alu.js".Alu.recogniseValue}. */
266
275
  export function decimalCodec(precision) {
267
- const enc = (v) => {
268
- switch (v.domain) {
269
- case "bit":
270
- return ASCII.encode(String(v.b));
271
- case "int":
272
- return ASCII.encode(v.n.toString());
273
- case "real":
274
- return ASCII.encode(formatReal(v.x, precision));
275
- case "symbol":
276
- return v.bytes;
277
- case "nd": {
278
- // [e0,e1,…] at the byte level, so a symbol element's arbitrary
279
- // (possibly non-ASCII / multimodal) bytes pass through untouched.
280
- const OPEN = ASCII.encode("[");
281
- const CLOSE = ASCII.encode("]");
282
- const COMMA = ASCII.encode(",");
283
- const parts = [OPEN];
284
- for (let i = 0; i < v.items.length; i++) {
285
- if (i > 0)
286
- parts.push(COMMA);
287
- parts.push(enc(v.items[i]));
288
- }
289
- parts.push(CLOSE);
290
- return concatBytes(parts);
291
- }
276
+ const enc = (v) => {
277
+ switch (v.domain) {
278
+ case "bit":
279
+ return ASCII.encode(String(v.b));
280
+ case "int":
281
+ return ASCII.encode(v.n.toString());
282
+ case "real":
283
+ return ASCII.encode(formatReal(v.x, precision));
284
+ case "symbol":
285
+ return v.bytes;
286
+ case "nd": {
287
+ // [e0,e1,…] at the byte level, so a symbol element's arbitrary
288
+ // (possibly non-ASCII / multimodal) bytes pass through untouched.
289
+ const OPEN = ASCII.encode("[");
290
+ const CLOSE = ASCII.encode("]");
291
+ const COMMA = ASCII.encode(",");
292
+ const parts = [OPEN];
293
+ for (let i = 0; i < v.items.length; i++) {
294
+ if (i > 0) {
295
+ parts.push(COMMA);
296
+ }
297
+ parts.push(enc(v.items[i]));
292
298
  }
293
- };
294
- return {
295
- encode: enc,
296
- decode(bytes) {
297
- return parseValue(bytes);
298
- },
299
- };
299
+ parts.push(CLOSE);
300
+ return concatBytes(parts);
301
+ }
302
+ }
303
+ };
304
+ return {
305
+ encode: enc,
306
+ decode(bytes) {
307
+ return parseValue(bytes);
308
+ },
309
+ };
300
310
  }