@hviana/sema 0.9.3 → 0.9.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.
- package/AGENTS.md +16 -7
- package/dist/src/mind/learning.js +11 -12
- package/dist/src/mind/mind.js +4 -4
- package/dist/src/mind/types.d.ts +10 -15
- package/dist/src/store.d.ts +10 -10
- package/dist/src/store.js +5 -5
- package/docs/INDEX.md +62 -59
- package/docs/INVARIANTS.md +36 -18
- package/docs/PHILOSOPHY.md +317 -0
- package/docs/architecture/bounded-reads.md +31 -71
- package/docs/architecture/caches.md +61 -81
- package/docs/architecture/closure.md +88 -107
- package/docs/architecture/commonality.md +47 -38
- package/docs/architecture/cost-model.md +57 -79
- package/docs/architecture/determinism.md +43 -55
- package/docs/architecture/evidence.md +158 -235
- package/docs/architecture/exact-vs-approximate.md +41 -35
- package/docs/architecture/factored-machinery.md +34 -20
- package/docs/architecture/fold-contract.md +110 -118
- package/docs/architecture/halo-sketch.md +105 -96
- package/docs/architecture/match-project.md +51 -42
- package/docs/architecture/mechanism-market.md +87 -91
- package/docs/architecture/memoization.md +60 -74
- package/docs/architecture/meter.md +37 -47
- package/docs/architecture/saturation.md +75 -101
- package/docs/architecture/store.md +118 -99
- package/docs/architecture/thresholds.md +66 -73
- package/docs/failures/tempting-but-wrong.md +139 -165
- package/docs/harness/gates.md +27 -32
- package/docs/mechanisms/alu.md +22 -69
- package/docs/mechanisms/cast.md +76 -71
- package/docs/mechanisms/confluence.md +22 -29
- package/docs/mechanisms/cover.md +58 -66
- package/docs/mechanisms/extraction.md +33 -37
- package/docs/mechanisms/prefix-completion.md +36 -39
- package/docs/mechanisms/recall.md +60 -53
- package/docs/mechanisms/reference.md +63 -49
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/alu/README.md +90 -298
- package/src/derive/README.md +94 -256
- package/src/mind/learning.ts +11 -12
- package/src/mind/mind.ts +4 -4
- package/src/mind/types.ts +10 -15
- package/src/rabitq-ivf/README.md +11 -8
- package/src/store.ts +5 -5
package/src/alu/README.md
CHANGED
|
@@ -1,304 +1,106 @@
|
|
|
1
1
|
# alu
|
|
2
2
|
|
|
3
3
|
A small, dependency-free **ALU**: a tiny irreducible kernel from which
|
|
4
|
-
arithmetic,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 2. Arithmetic — the field-and-order layer (`kernel-arith.ts`, `kernel-bits.ts`)
|
|
41
|
-
|
|
42
|
-
Identities `0`, `1`; primitives `add`, `negate`, `multiply`, `reciprocal`,
|
|
43
|
-
`sign` (plus optional `floor` / `mod` for integer number theory). Derived:
|
|
44
|
-
`subtract = add ∘ negate`, `divide = multiply ∘ reciprocal`, every comparison
|
|
45
|
-
`= sign ∘ subtract`, then `abs`, `min`, `max`, `power`, `gcd`, and the array
|
|
46
|
-
routines `polyEval`, `dot`, `matMul`, `linsolve` (Gaussian elimination — just
|
|
47
|
-
structured arithmetic, _not_ a new primitive).
|
|
48
|
-
|
|
49
|
-
**The bit-vector bootstrap is exact and exercised.** `kernel-bits.ts` builds
|
|
50
|
-
`full_adder` from the `xor`/`and`/`or` of layer 1, and from it derives ripple
|
|
51
|
-
`add` → two's-complement `negate` → shift-add `multiply` → `sign` → `compare`,
|
|
52
|
-
all on exact `bigint`. This is the literal proof that "add … everything derives
|
|
53
|
-
from nand"; the tests cross-check each against native `bigint`. It runs under a
|
|
54
|
-
`bits.` namespace so it is a separately-testable _exhibit_, never silently the
|
|
55
|
-
substrate of a real-number computation.
|
|
56
|
-
|
|
57
|
-
The arithmetic primitives are **polymorphic over the numeric domains**: when all
|
|
58
|
-
operands are exact (`bit`/`int`) they run on `bigint` and agree with the
|
|
59
|
-
bootstrap; the moment a `real` appears the expression lifts to IEEE doubles,
|
|
60
|
-
which is what the limit layer needs.
|
|
61
|
-
|
|
62
|
-
### 3. Numerical — the limit layer (`kernel-numeric.ts`)
|
|
63
|
-
|
|
64
|
-
One primitive: **`converge(step, tol)`** — iterate a refinement until successive
|
|
65
|
-
results agree within ε. This is the _only_ thing that makes the engine numerical
|
|
66
|
-
rather than a classical (exact, finite) ALU. Exposed: `diff`, `integrate`,
|
|
67
|
-
`solve`; derived: `exp`, `log`, `sin`, `cos`, `sqrt`, `optimize`
|
|
68
|
-
(`= solve(diff
|
|
69
|
-
f)`), `odeSolve`, `regress` (`= linsolve` on the normal
|
|
70
|
-
equations), `interpolate`, `powerEig` / `topSingular` (power iteration
|
|
71
|
-
`= converge`).
|
|
72
|
-
|
|
73
|
-
### 4. N-dimensional — the list layer (`kernel-nd.ts`)
|
|
74
|
-
|
|
75
|
-
A value may also be an **`nd`**: an ordered list whose elements are _themselves_
|
|
76
|
-
values of any domain — a scalar, or another `nd`. That one recursive case is the
|
|
77
|
-
whole generalisation: a matrix is an `nd` of `nd`s, a ragged table is an `nd` of
|
|
78
|
-
unequal-length `nd`s, a heterogeneous row mixes a number, a symbol, and a
|
|
79
|
-
sub-list. There is no separate vector/matrix type and no new primitive per rank.
|
|
80
|
-
|
|
81
|
-
Three structural primitives — the only ops that touch a list's elements:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
nd(a, b, …) pack operands into a list (construct)
|
|
85
|
-
length(xs) the top-level element count (measure)
|
|
86
|
-
at(xs, i) the i-th element, ±from end (project)
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Everything else derives from those three plus the scalar kernels. The
|
|
90
|
-
higher-order ops take an **operation as their argument**, resolved by the _same_
|
|
91
|
-
machinery any operator is (a surface form, else its resonant meaning — see
|
|
92
|
-
`OpContext.resolveOp`), so the fold/transform/predicate is **any operation the
|
|
93
|
-
kernel already has**, never a bespoke table:
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
map(xs, f) = nd( f(at xs i) for i in 0…length xs )
|
|
97
|
-
filter(xs, p) = the elements where p holds
|
|
98
|
-
reduce(xs, f[,z]) = f(… f(f(z, at xs 0), at xs 1) …) reduce(xs,+)=sum, (xs,*)=product, (xs,max)=maximum
|
|
99
|
-
find(xs, p) = the first element where p holds, else the empty nd
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
plus `concat`, `reverse`, `flatten`, `zip`, `range`, `rank` (nesting depth),
|
|
103
|
-
`shape`. Because `reduce`'s `f(acc, elem)` re-enters `apply`, a `reduce(rows,+)`
|
|
104
|
-
broadcasts `+` over the row-lists — a column sum falls out, no matrix code.
|
|
105
|
-
|
|
106
|
-
## The irreducible kernel
|
|
107
|
-
|
|
108
|
-
- one gate — `nand`
|
|
109
|
-
- two identities + six ops — `0, 1, add, negate, multiply, reciprocal, sign` (+
|
|
110
|
-
optional `floor`/`mod`)
|
|
111
|
-
- one limit operator — `converge`
|
|
112
|
-
- three structural ops — `nd, length, at`
|
|
113
|
-
|
|
114
|
-
Everything else is a rewrite rule over those.
|
|
115
|
-
|
|
116
|
-
## Values: byte-native, multimodal, and n-dimensional
|
|
117
|
-
|
|
118
|
-
SEMA computes on bytes of any modality, so ALU's value is a tagged union
|
|
119
|
-
(`value.ts`) — four scalar domains plus the recursive container:
|
|
4
|
+
arithmetic, logic and numerical computation are all _derived_. The operations a
|
|
5
|
+
mind should not have to learn one number at a time are declared here once: how
|
|
6
|
+
to add 2 and 2, how to negate a truth value. It imports nothing from the rest of
|
|
7
|
+
the codebase except the pure byte helpers in `../bytes.ts`, and its tests run
|
|
8
|
+
with no Sema dependency.
|
|
9
|
+
|
|
10
|
+
## One tiny kernel; everything else is a rewrite
|
|
11
|
+
|
|
12
|
+
Each layer declares only its irreducible primitives and derives everything else
|
|
13
|
+
from them.
|
|
14
|
+
|
|
15
|
+
| Layer | Primitives | Derived |
|
|
16
|
+
| ----------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| **Logic** (`kernel-logic.ts`) | `nand`, which is functionally complete on its own | `not`, `and`, `or`, `nor`, `xor`, `xnor`, `implies`, `iff`, and `mux(s, a, b)`, the bridge to control flow |
|
|
18
|
+
| **Arithmetic** (`kernel-arith.ts`) | `0`, `1`, `add`, `negate`, `multiply`, `reciprocal`, `sign` (+ optional `floor`, `mod`) | `subtract`, `divide`, every comparison (`sign ∘ subtract`), `abs`, `min`, `max`, `power`, `gcd`, `polyEval`, `dot`, `matMul`, `linsolve` |
|
|
19
|
+
| **Numerical** (`kernel-numeric.ts`) | `converge(step, tol)`: iterate until successive results agree within ε | `diff`, `integrate`, `solve`, `exp`, `log`, `sin`, `cos`, `sqrt`, `optimize`, `odeSolve`, `regress`, `interpolate`, `powerEig`, `topSingular` |
|
|
20
|
+
| **N-dimensional** (`kernel-nd.ts`) | `nd(a, b, …)`, `length(xs)`, `at(xs, i)` | `map`, `filter`, `reduce`, `find`, `concat`, `reverse`, `flatten`, `zip`, `range`, `rank`, `shape` |
|
|
21
|
+
|
|
22
|
+
- **`converge` is what makes the engine numerical** rather than a classical,
|
|
23
|
+
exact and finite ALU.
|
|
24
|
+
- **The bit-vector bootstrap is exact and exercised.** `kernel-bits.ts` builds
|
|
25
|
+
`full_adder` from the logic layer. From it come ripple `add`, two's-complement
|
|
26
|
+
`negate`, shift-add `multiply`, `sign` and `compare`, all on `bigint`, and
|
|
27
|
+
they are cross-checked against native `bigint`. It lives under a `bits.`
|
|
28
|
+
namespace, as a separately tested exhibit, never as the silent substrate of a
|
|
29
|
+
real-number computation.
|
|
30
|
+
- **Arithmetic is polymorphic over domains.** Exact operands (`bit`, `int`) run
|
|
31
|
+
on `bigint`. Once a `real` appears, the expression lifts to IEEE doubles.
|
|
32
|
+
- **The higher-order list operations take an operation as an argument.** It is
|
|
33
|
+
resolved by the same machinery as any operator: a surface form, or else its
|
|
34
|
+
resonant meaning (`OpContext.resolveOp`). For example, `reduce(xs, +)` is a
|
|
35
|
+
sum, and `reduce(rows, +)` is a column sum.
|
|
36
|
+
|
|
37
|
+
## Values — byte-native, any modality, n-dimensional (`value.ts`)
|
|
120
38
|
|
|
121
39
|
```ts
|
|
122
40
|
type Value =
|
|
123
41
|
| { domain: "bit"; b: 0 | 1 }
|
|
124
42
|
| { domain: "int"; n: bigint }
|
|
125
43
|
| { domain: "real"; x: number }
|
|
126
|
-
| { domain: "symbol"; bytes: Uint8Array }
|
|
44
|
+
| { domain: "symbol"; bytes: Uint8Array } // an opaque byte span of any modality
|
|
127
45
|
| { domain: "nd"; items: Value[] }; // recursive: a list of any-domain values
|
|
128
46
|
```
|
|
129
47
|
|
|
130
|
-
A
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
not by arithmetic. That single `inverse` op dispatches on the operand's domain —
|
|
135
|
-
so "the inverse of 3 is −3" and "the opposite of ‹a learned form› is ‹its
|
|
136
|
-
resonant opposite›" are one operation.
|
|
137
|
-
|
|
138
|
-
An **`nd`** is the recursive container above. The default codec spells it as a
|
|
139
|
-
bracket literal `[e0,e1,…]` (nestable, heterogeneous) that round-trips through
|
|
140
|
-
`parseValue`; a symbol element keeps its raw bytes, so a list of any modality
|
|
141
|
-
survives.
|
|
142
|
-
|
|
143
|
-
### Every operation supports `nd`, via one mechanism: **broadcast**
|
|
144
|
-
|
|
145
|
-
A scalar op applied to a list lifts over it element-wise, and because each
|
|
146
|
-
element re-enters `apply`, nesting recurses with no extra code — `add`, `sin`,
|
|
147
|
-
`nand`, and the polymorphic `inverse` all broadcast for free:
|
|
148
|
-
|
|
149
|
-
```
|
|
150
|
-
add([1,2,3], [4,5,6]) = [5,7,9] two lists zip
|
|
151
|
-
add([1,2,3], 10) = [11,12,13] a scalar is held constant
|
|
152
|
-
add([[1,2],[3,4]], …) recurses a matrix op is the same op
|
|
153
|
-
inverse([large,3,tall]) = [small,-3,short] numbers negate, symbols resonate
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
This is implemented in exactly one place (`OperationRegistry.context`). The list
|
|
157
|
-
layer's own ops are marked **structural** (broadcast-exempt) — a `reduce` must
|
|
158
|
-
see the whole list, not be lifted across the very elements it folds. The two
|
|
159
|
-
halves of "all operations support nd" — scalar ops broadcasting _down_ into
|
|
160
|
-
lists, structural ops consuming lists _whole_ — meet exactly there.
|
|
161
|
-
|
|
162
|
-
## How it joins the SEMA search
|
|
163
|
-
|
|
164
|
-
The ALU is completely decoupled from Sema. It joins the mind through
|
|
165
|
-
`aluToMechanism` ([`../mind/mechanisms/alu.ts`](../mind/mechanisms/alu.ts),
|
|
166
|
-
re-exported from [`../mind/pipeline.ts`](../mind/pipeline.ts)), a thin adapter
|
|
167
|
-
that wraps the ALU's `parse` in a `PipelineMechanism` — the same uniform
|
|
168
|
-
interface every grounding mechanism (CAST, confluence, cover, extraction,
|
|
169
|
-
recall) implements, so nothing about the ALU is special-cased.
|
|
170
|
-
|
|
171
|
-
### The contract
|
|
172
|
-
|
|
173
|
-
`PipelineMechanism`'s `parse` is the part the ALU actually uses:
|
|
174
|
-
|
|
175
|
-
```ts
|
|
176
|
-
interface PipelineMechanism {
|
|
177
|
-
parse?(query: Uint8Array): Promise<ComputedSpan[]>;
|
|
178
|
-
floor(ctx, query, pre, worthRunning): Promise<number | null>;
|
|
179
|
-
run(ctx, query, pre): Promise<MechanismResult[]>;
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
A `ComputedSpan` is `{ i, j, bytes }` — a half-open byte range and the
|
|
184
|
-
authoritative result bytes computed for it.
|
|
185
|
-
|
|
186
|
-
At construction, every extension factory receives an `ExtensionHost` — four
|
|
187
|
-
neutral capabilities the mind already has for its own purposes:
|
|
188
|
-
|
|
189
|
-
```ts
|
|
190
|
-
interface ExtensionHost {
|
|
191
|
-
meaningOf(
|
|
192
|
-
bytes: Uint8Array,
|
|
193
|
-
anchors: ReadonlyArray<{ name: string; form: Uint8Array }>,
|
|
194
|
-
): Promise<string | null>;
|
|
195
|
-
continuation(bytes: Uint8Array): Promise<Uint8Array | null>;
|
|
196
|
-
segment(bytes: Uint8Array): Array<{ i: number; j: number }>;
|
|
197
|
-
reach: number;
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
The host port knows nothing about ALU. The ALU adapts it into the specialised
|
|
202
|
-
`AluResonance` ([`resonance.ts`](src/resonance.ts)) it needs:
|
|
203
|
-
|
|
204
|
-
- `meaningOf` → `recogniseOp` — which registered operation does a span mean?
|
|
205
|
-
- `continuation` → `opposite` — the polymorphic inverse of a symbol
|
|
206
|
-
|
|
207
|
-
### The parser
|
|
208
|
-
|
|
209
|
-
The `QueryParser` ([`parser.ts`](src/parser.ts)) scans the raw query bytes for
|
|
210
|
-
two kinds of computation:
|
|
211
|
-
|
|
212
|
-
**Infix arithmetic** — literal numbers and symbolic operators (`"2+3*4"`). The
|
|
213
|
-
parser uses an expression grammar with precedence climbing
|
|
214
|
-
([`expr.ts`](src/expr.ts)) and byte-class constants ([`text.ts`](src/text.ts))
|
|
215
|
-
that are independent of the river's content-defined chunking, so a multi-digit
|
|
216
|
-
number the river would split across groups is still read whole. Each run is
|
|
217
|
-
evaluated through the kernel and emitted as a `ComputedSpan`.
|
|
218
|
-
|
|
219
|
-
**Operations by meaning** — a term may name an operation not by a literal
|
|
220
|
-
surface form (`"sqrt"`) but by _resonance_: its gist lands on a learned concept
|
|
221
|
-
anchor that was registered as an operation's meaning. This is the only path that
|
|
222
|
-
needs the host. The ALU also carries a `STRUCTURAL_HOST` constant — a host that
|
|
223
|
-
knows nothing beyond structure (whitespace-only segmentation, unbounded reach,
|
|
224
|
-
no resonance). Without a real host, the parser still reads literal notation;
|
|
225
|
-
only meaning-based paths stay silent.
|
|
48
|
+
**A symbol carries the polymorphic inverse.** The inverse of a number is its
|
|
49
|
+
negation. The inverse of a symbol is its resonant opposite, found in the
|
|
50
|
+
resonance space rather than by arithmetic. One `inverse` operation dispatches on
|
|
51
|
+
the operand's domain.
|
|
226
52
|
|
|
227
|
-
|
|
53
|
+
**An `nd` is the only container.** A matrix is an `nd` of `nd`s, and a ragged or
|
|
54
|
+
heterogeneous table needs no new type. Its literal is `[e0,e1,…]`, which
|
|
55
|
+
round-trips through `parseValue`.
|
|
228
56
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
57
|
+
**Broadcast is defined once** (`OperationRegistry.context`). A scalar operation
|
|
58
|
+
applied to a list lifts element-wise and recurses into nesting:
|
|
59
|
+
`add([1,2,3], 10) = [11,12,13]`, and
|
|
60
|
+
`inverse([large,3,tall]) =
|
|
61
|
+
[small,-3,short]`. Structural operations, marked with
|
|
62
|
+
the trailing `structural = true` flag, are exempt, because they consume a list
|
|
63
|
+
whole.
|
|
233
64
|
|
|
234
|
-
|
|
235
|
-
const sync = await prefetchResonance(resonance, spans);
|
|
236
|
-
// sync.ops: Map<bytes, OperationRecord> — operation by meaning
|
|
237
|
-
// sync.syms: Map<bytes, Uint8Array> — symbolic inverses
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
The synchronous op callbacks never await — they read from the pre-resolved
|
|
241
|
-
snapshots. A named operation applied to the query's operand stream resolves
|
|
242
|
-
opposites ON DEMAND (`withOppositesOnDemand`). The kernel runs against a
|
|
243
|
-
snapshot of the opposites resolved so far. When it asked for one of its symbol
|
|
244
|
-
operands that is not resolved yet, that one is resolved through the host and the
|
|
245
|
-
pure kernel runs again. The result is the eager prefetch's, but only the
|
|
246
|
-
polymorphic inverse reads opposites. Before this, every symbol operand of ANY
|
|
247
|
-
operation paid one host call, and on Sema each is a halo-index query (30–200 ms
|
|
248
|
-
of a plain dialogue turn's parse that computed nothing). The public
|
|
249
|
-
`Mind.compute(name, operands)` path pre-resolves every symbol span before the
|
|
250
|
-
synchronous kernel runs, using the same discipline.
|
|
251
|
-
|
|
252
|
-
### The mind loop
|
|
65
|
+
## How it joins a host
|
|
253
66
|
|
|
254
|
-
|
|
255
|
-
|
|
67
|
+
The ALU is a plain class (`alu.ts`) that exposes
|
|
68
|
+
`parse(query) →
|
|
69
|
+
ComputedSpan[]`. A `ComputedSpan` is `{ i, j, bytes }`: a
|
|
70
|
+
half-open byte range and the authoritative result computed for it. In Sema,
|
|
71
|
+
`aluToMechanism` wraps it as an ordinary pipeline mechanism. Computed spans mask
|
|
72
|
+
the recognised sites they overlap, which is how computation always wins
|
|
73
|
+
(`docs/mechanisms/alu.md`).
|
|
256
74
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
```
|
|
75
|
+
**The host port.** At construction the ALU receives an `ExtensionHost`, four
|
|
76
|
+
neutral capabilities that know nothing about the ALU:
|
|
77
|
+
`meaningOf(bytes, anchors)`, `continuation(bytes)`, `segment(bytes)` and
|
|
78
|
+
`reach`. The ALU adapts them into its own `AluResonance` (`resonance.ts`):
|
|
262
79
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
whose span overlaps a computed span is **masked** before the search. This is the
|
|
266
|
-
"computation always wins" policy: a deliberately-trained `2+2 → 5` is masked;
|
|
267
|
-
the computed `4` is the cover's sole completion there. The search itself stays a
|
|
268
|
-
neutral cost engine (a computed `Out` and a learned edge both cost `STEP`);
|
|
269
|
-
precedence lives entirely in the masking step, which is in
|
|
270
|
-
`src/mind/mechanisms/cover.ts`, not in the search and not in the ALU.
|
|
80
|
+
- `meaningOf` becomes `recogniseOp`: which operation does this span mean?
|
|
81
|
+
- `continuation` becomes `opposite`: a symbol's inverse.
|
|
271
82
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
only.
|
|
83
|
+
Without a host (`STRUCTURAL_HOST`), the parser still reads literal notation, and
|
|
84
|
+
only the paths that depend on meaning stay silent.
|
|
275
85
|
|
|
276
|
-
|
|
86
|
+
**The parser** (`parser.ts`, with its grammar in `expr.ts` and byte classes in
|
|
87
|
+
`text.ts`) finds two kinds of computation:
|
|
277
88
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
↑ aluToMechanism(alu) wraps
|
|
283
|
-
Alu ← plain class, no mechanism shape
|
|
284
|
-
↑ receives at construction
|
|
285
|
-
ExtensionHost port ← 4 neutral capabilities
|
|
286
|
-
↑ mind.extensionHost()
|
|
287
|
-
AluResonance adapter ← specialised reading
|
|
288
|
-
↑ parser.ts QueryParser
|
|
289
|
-
```
|
|
89
|
+
- **Infix arithmetic** (`2+3*4`), read with precedence climbing and independent
|
|
90
|
+
of any chunking, so a multi-digit number is always read whole.
|
|
91
|
+
- **Operations named by meaning,** where a term's gist lands on a learnt anchor
|
|
92
|
+
registered as an operation's meaning.
|
|
290
93
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
computed spans mask recall with the same precedence.
|
|
94
|
+
**Asynchronous reads are resolved before the synchronous kernel runs.**
|
|
95
|
+
`prefetchResonance` resolves operations by meaning. Opposites are resolved on
|
|
96
|
+
demand (`withOppositesOnDemand`): the kernel runs against the opposites resolved
|
|
97
|
+
so far, and is re-run only when it asked for a missing one. Before this, every
|
|
98
|
+
symbol operand of every operation paid one halo query, 30–200 ms of a plain
|
|
99
|
+
dialogue turn that computed nothing.
|
|
298
100
|
|
|
299
101
|
## Adding an operation
|
|
300
102
|
|
|
301
|
-
|
|
103
|
+
Add one declarative call:
|
|
302
104
|
|
|
303
105
|
```ts
|
|
304
106
|
registry.derive("hypot", 2, ["hypot"], (args, ctx) =>
|
|
@@ -310,30 +112,20 @@ registry.derive("hypot", 2, ["hypot"], (args, ctx) =>
|
|
|
310
112
|
]));
|
|
311
113
|
```
|
|
312
114
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
only for an op that consumes a list _whole_, like the `nd` kernel's own.
|
|
115
|
+
Give it a name, its surface forms, and a body made of existing operations. No
|
|
116
|
+
kernel, search or resonance edit is needed. A scalar operation broadcasts over
|
|
117
|
+
`nd` automatically.
|
|
317
118
|
|
|
318
119
|
## Layout
|
|
319
120
|
|
|
320
121
|
```
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
│ ├── kernel-logic.ts nand → not/and/or/nor/xor/xnor/implies/iff/mux
|
|
331
|
-
│ ├── kernel-bits.ts the exact full_adder→add→multiply bootstrap (bigint)
|
|
332
|
-
│ ├── kernel-arith.ts identities + add/negate/multiply/reciprocal/sign + derived
|
|
333
|
-
│ ├── kernel-numeric.ts converge → diff/integrate/solve → exp/log/sin/cos/sqrt/…
|
|
334
|
-
│ ├── kernel-nd.ts nd/length/at → map/reduce/filter/find/concat/zip/rank/shape
|
|
335
|
-
│ ├── alu.ts the assembled Alu: exposes parse(), owns the parser
|
|
336
|
-
│ └── index.ts public surface
|
|
337
|
-
└── test/
|
|
338
|
-
└── alu.test.ts self-contained tests (no Sema dependency)
|
|
122
|
+
src/value.ts the Value union and the byte ⇄ value codec
|
|
123
|
+
src/operation.ts Operation records and the registry; derivations compose by name
|
|
124
|
+
src/parser.ts QueryParser: infix arithmetic and operations by meaning
|
|
125
|
+
src/expr.ts, text.ts the expression grammar and the byte classes
|
|
126
|
+
src/resonance.ts AluResonance and the async → sync pre-resolution
|
|
127
|
+
src/kernel-*.ts logic, bits, arith, numeric, nd
|
|
128
|
+
src/alu.ts the assembled Alu
|
|
129
|
+
src/index.ts public surface
|
|
130
|
+
test/alu.test.ts self-contained tests
|
|
339
131
|
```
|