monogate 0.1.0 → 0.2.0

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/README.md CHANGED
@@ -18,10 +18,17 @@ Live explorer: **https://monogate.dev** (or your deployed URL)
18
18
 
19
19
  ## Install
20
20
 
21
+ **JavaScript / Node**
21
22
  ```bash
22
23
  npm install monogate
23
24
  ```
24
25
 
26
+ **Python**
27
+ ```bash
28
+ pip install monogate # core only (no dependencies)
29
+ pip install "monogate[torch]" # + PyTorch differentiable ops + EMLTree / EMLNetwork
30
+ ```
31
+
25
32
  ## Usage
26
33
 
27
34
  ```js
@@ -79,7 +86,7 @@ These functions have no known EML construction:
79
86
  - **sin x** — no construction found
80
87
  - **cos x** — no construction found
81
88
  - **π** — no construction as a closed EML expression
82
- - **i** (√−1) — requires extending the domain
89
+ - **i** (√−1) — open under strict principal-branch grammar. Under the extended-reals convention (`ln(0) = −∞`), i is constructible from `{1}` alone in K=75 nodes ([pveierland/eml-eval](https://github.com/pveierland/eml-eval)). These are different grammars, not contradictory results.
83
90
 
84
91
  Pull requests welcome. If you crack one, open an issue — it's publishable.
85
92
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monogate",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A single binary operator eml(x,y) = exp(x) − ln(y) that generates all elementary functions. Implementation of arXiv:2603.21852 (Odrzywołek, 2026).",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -24,11 +24,11 @@
24
24
  "license": "MIT",
25
25
  "repository": {
26
26
  "type": "git",
27
- "url": "https://github.com/your-username/monogate.git"
27
+ "url": "https://github.com/almaguer1986/monogate.git"
28
28
  },
29
- "homepage": "https://monogate.dev",
29
+ "homepage": "https://github.com/almaguer1986/monogate",
30
30
  "bugs": {
31
- "url": "https://github.com/your-username/monogate/issues"
31
+ "url": "https://github.com/almaguer1986/monogate/issues"
32
32
  },
33
33
  "engines": {
34
34
  "node": ">=16"
@@ -11,18 +11,24 @@
11
11
  * ── Key results ──────────────────────────────────────────────────────────────
12
12
  *
13
13
  * ONE-TERMINAL RESULT (proven):
14
- * S → 1 | eml_c(S,S) constructs −iπ in 12 nodes, depth 8.
14
+ * S → 1 | eml_c(S,S) constructs −iπ in 11 nodes, depth 8.
15
15
  * This is the first non-real value reachable from a single real terminal.
16
16
  *
17
17
  * TWO-TERMINAL RESULT (proven):
18
18
  * S → 1 | 2 | eml_c(S,S) constructs i, π, and Euler's formula
19
19
  * exp(ix) = cos(x) + i·sin(x) as a single EML expression.
20
20
  *
21
- * OPEN PROBLEM:
22
- * Does S → 1 | eml_c(S,S) generate i?
21
+ * OPEN PROBLEM (strict principal-branch grammar):
22
+ * Does S → 1 | eml_c(S,S) generate i, where ln_c(0) is undefined?
23
23
  * Equivalently: is there a finite EML tree over terminal {1} that evaluates
24
- * to 0 + 1·i under complex extension with principal-branch ln?
25
- * This is an open question in transcendental number theory.
24
+ * to 0 + 1·i without passing 0 through ln_c at any intermediate node?
25
+ *
26
+ * Note: Under the extended-reals convention (ln(0) = −∞, as in the original
27
+ * paper and pveierland/eml-eval), i IS constructible from {1} alone in
28
+ * K=75 nodes, depth=19, via exp(ln(−1)/2) where 2 = add(1,1).
29
+ * The two results are not contradictory — they characterize different grammars.
30
+ * This library uses strict principal-branch ln; whether i is reachable under
31
+ * that convention remains open.
26
32
  *
27
33
  * SIN / COS LIMITATION:
28
34
  * sin(x) = Im(eul_c(x)) and cos(x) = Re(eul_c(x)).
@@ -239,51 +245,60 @@ export const pow_c = (x, n) => op_c(mul_c(_wrap(n), ln_c(_wrap(x))), one);
239
245
  // a NEGATIVE REAL reaches the y-position, causing ln_c to apply its
240
246
  // principal branch and return a value with imaginary part ±π.
241
247
  //
242
- // neg_real(1) = −1 is constructible from the ONE-TERMINAL real grammar
243
- // (nodes:9, depth:5). All intermediate ln arguments in that construction
244
- // are positive reals — the negation is achieved without ever applying ln
245
- // to a negative number. The result −1 is then passed as the y-argument
246
- // of an outer eml_c, triggering the branch cut.
248
+ // 11-NODE CONSTRUCTION (current best, pure one-terminal tree):
249
+ //
250
+ // eml(1, eml(eml(1, eml(eml(eml(eml(1,eml(1,1)),1),1),1)), eml(eml(eml(1,1),1),1)))
251
+ //
252
+ // Step 1: tower = eml(eml(eml(eml(1,eml(1,1)),1),1),1)
253
+ // Starting from e = eml(1,1):
254
+ // eml(1,e) = e−1 → eml(e−1,1) = exp(e−1) → eml(...,1) = exp(exp(e−1))
255
+ // → eml(...,1) = exp(exp(exp(e−1))) [≈ 3.45×10¹¹⁴]
247
256
  //
248
- // Step 1: z₁ = eml_c(1, −1)
249
- // = exp(1) ln_c(−1)
250
- // = e − iπ [principal branch: arg(−1) = π]
251
- // Nodes: 10 Depth: 6
257
+ // Step 2: A = eml(1, tower) = e ln(tower) ≈ e − exp(exp(e−1)) < 0
258
+ // (A is a large negative real)
252
259
  //
253
- // Step 2: z₂ = eml_c(z₁, 1)
254
- // = exp_c(e − iπ) − 0
255
- // = exp(e) · exp(−iπ)
256
- // = −exp(e) [real, negative → second branch-cut trigger]
257
- // Nodes: 11 Depth: 7
260
+ // Step 3: B = eml(eml(eml(1,1),1),1) = exp(exp(e)) [≈ 3.81×10⁶]
258
261
  //
259
- // Step 3: z₃ = eml_c(1, z₂)
260
- // = e ln_c(exp(e))
261
- // = e (e + iπ)
262
- // = −iπ [exact, one-terminal result]
263
- // Nodes: 12 Depth: 8
262
+ // Step 4: mid = eml(A, B) = exp_c(A) − ln_c(B)
263
+ // exp(A) 0 (A ≪ 0), ln(exp(exp(e))) = exp(e) = e^e
264
+ // mid −e^e [real, negative → branch-cut trigger]
264
265
  //
265
- // IEEE 754 CAVEAT: sin(−π) ≈ −1.22e-16 0. In floating-point, z₂ has a
266
- // tiny negative imaginary part, so atan2 returns −π (not ), giving:
267
- // ln_c(z₂)_float = [e, −π], and z₃_float = e − (e − iπ) = +iπ.
268
- // Both ±iπ are mathematically valid; code must not assume a sign.
269
- // Assertion: abs(NEG_I_PI_C.re) < 1e-10 AND abs(|NEG_I_PI_C.im| − π) < 1e-10
266
+ // Step 5: result = eml(1, mid) = e ln_c(−e^e)
267
+ // = e (ln(e^e) + iπ) = e (e + iπ) = −iπ ✓
268
+ // Nodes: 11 Depth: 8
270
269
  //
271
- // Full tree (pure EML notation):
272
- // eml_c(1, eml_c(eml_c(1, neg_real(1)), 1))
273
- // where neg_real(1) is the 9-node real EML tree for −1.
270
+ // ADVANTAGE OVER PRIOR 12-NODE CONSTRUCTION:
271
+ // The 12-node construction (via neg_real(1) = −1) produces z₂ = −exp(e)
272
+ // with a floating-point imaginary part −1.22e−16, causing atan2 to return
273
+ // −π instead of +π and yielding +iπ rather than −iπ in floating-point.
274
+ // The 11-node construction avoids this: A is a large negative real with
275
+ // zero imaginary part, so −e^e is cleanly negative and ln_c gives exactly
276
+ // e + iπ with no sign ambiguity.
277
+ //
278
+ // Assertion: abs(NEG_I_PI_C.re) < 1e-10 AND NEG_I_PI_C.im < 0
279
+ // (imaginary part is reliably negative with this construction)
274
280
  // ─────────────────────────────────────────────────────────────────────────────
275
281
 
276
- const _neg_real_one = Complex.of(neg_real(1)); // = −1 via real EML grammar
277
-
278
282
  /**
279
- * −iπ (or +iπ in floating-point; see ESCAPE comment above).
283
+ * −iπ first complex constant reachable from terminal {1} alone.
280
284
  *
281
- * The FIRST complex constant reachable from terminal {1} alone under the
282
- * complex extension S → 1 | eml_c(S,S). Nodes:12 Depth:8.
285
+ * Pure one-terminal construction: S 1 | eml_c(S,S), nodes=11, depth=8.
286
+ * Expression: eml(1,eml(eml(1,eml(eml(eml(eml(1,eml(1,1)),1),1),1)),eml(eml(eml(1,1),1),1)))
283
287
  *
284
- * Verified: |Re| < 1e-10, ||Im| π| < 1e-10
288
+ * Verified: |Re| < 1e-10, Im −π (sign is reliable, unlike the 12-node construction)
285
289
  */
286
- export const NEG_I_PI_C = op_c(one, op_c(op_c(one, _neg_real_one), one));
290
+ // Build from inside out (see ESCAPE comment above)
291
+ const _e = op_c(one, one); // eml(1,1) = e
292
+ const _em1 = op_c(one, _e); // eml(1,e) = e−1
293
+ const _t1 = op_c(_em1, one); // eml(e−1,1) = exp(e−1)
294
+ const _t2 = op_c(_t1, one); // eml(...,1) = exp(exp(e−1))
295
+ const _tower = op_c(_t2, one); // eml(...,1) = exp(exp(exp(e−1))) [huge]
296
+ const _neg_br = op_c(one, _tower); // eml(1,tower) < 0 [negative real]
297
+ const _ee = op_c(one, one); // eml(1,1) = e (independent subtree)
298
+ const _exp_e = op_c(_ee, one); // eml(e,1) = exp(e)
299
+ const _exp_ee = op_c(_exp_e, one); // eml(exp(e),1) = exp(exp(e))
300
+ const _mid = op_c(_neg_br, _exp_ee); // eml(neg,B) ≈ −exp(e) [branch-cut trigger]
301
+ export const NEG_I_PI_C = op_c(one, _mid); // eml(1,−e^e) = −iπ
287
302
 
288
303
  /**
289
304
  * ±iπ/2 — half of NEG_I_PI_C, used to construct i.
@@ -493,13 +508,13 @@ export const IDENTITIES_C = [
493
508
  },
494
509
  {
495
510
  name: "−iπ",
496
- emlForm: "eml_c(1, eml_c(eml_c(1, neg_real(1)), 1))",
497
- nodes: 12, depth: 8,
511
+ emlForm: "eml(1,eml(eml(1,eml(eml(eml(eml(1,eml(1,1)),1),1),1)),eml(eml(eml(1,1),1),1)))",
512
+ nodes: 11, depth: 8,
498
513
  domain: "constant",
499
- branchCut: "branch cut at z₂ = −exp(e); float gives +iπ or −iπ",
514
+ branchCut: "branch cut at mid = −exp(e); Im is reliably −π (no float sign ambiguity)",
500
515
  terminal: "{1}",
501
516
  status: "proven",
502
- note: "First non-real value constructible from a single real terminal",
517
+ note: "First non-real value constructible from a single real terminal (improved from 12 nodes)",
503
518
  },
504
519
  {
505
520
  name: "i",
package/src/index.js CHANGED
@@ -149,21 +149,265 @@ export const pow = (x, n) => op(mul(n, ln(x)), 1);
149
149
  */
150
150
  export const recip = (x) => op(neg(ln(x)), 1);
151
151
 
152
+ // ─── EDL operator ─────────────────────────────────────────────────────────────
153
+ //
154
+ // edl(x, y) = exp(x) / ln(y)
155
+ // Natural constant: Math.E (ln(e) = 1 → edl(x,e) = exp(x))
156
+ // Domain: y > 0, y ≠ 1 (ln(1) = 0 causes division by zero)
157
+ // EDL and EML are the two known complete operator families.
158
+
159
+ /**
160
+ * The EDL operator: edl(x, y) = exp(x) / ln(y)
161
+ *
162
+ * @param {number} x
163
+ * @param {number} y must be > 0 and ≠ 1
164
+ * @returns {number}
165
+ */
166
+ export const edl = (x, y) => Math.exp(x) / Math.log(y);
167
+
168
+ /** EDL natural constant: e (ln(e)=1 → edl(x,e)=exp(x)) */
169
+ export const EDL_E = Math.E;
170
+
171
+ // EDL exp: edl(x, e) = exp(x) / ln(e) = exp(x)
172
+ const _exp_edl = (x) => edl(x, EDL_E);
173
+
174
+ // EDL ln: edl(0, edl(edl(0,x), e)) — 3-node tree
175
+ // step 1: edl(0, x) = 1/ln(x)
176
+ // step 2: edl(s, e) = exp(1/ln(x))
177
+ // step 3: edl(0, t) = 1/(1/ln(x)) = ln(x) ✓
178
+ // Dead zone: x near 1 causes step 2 to overflow (ln(x) → 0)
179
+ const _ln_edl = (x) => edl(0, edl(edl(0, x), EDL_E));
180
+
181
+ /**
182
+ * x / y — EDL's natural 1-node operation: edl(ln(x), exp(y))
183
+ * Proof: exp(ln(x)) / ln(exp(y)) = x / y ∎
184
+ * Nodes: 1 (vs EML's 15) Domain: x > 0, y ≠ 0
185
+ *
186
+ * @param {number} x must be > 0
187
+ * @param {number} y must be ≠ 0
188
+ * @returns {number}
189
+ */
190
+ export const div_edl = (x, y) => edl(_ln_edl(x), _exp_edl(y));
191
+
192
+ /**
193
+ * 1/x — 2-node EDL tree: edl(0, edl(x, e))
194
+ * Proof: edl(x,e)=exp(x); edl(0,exp(x))=1/ln(exp(x))=1/x ∎
195
+ * Nodes: 2 (vs EML's 5) Domain: x ≠ 0
196
+ *
197
+ * @param {number} x must be ≠ 0
198
+ * @returns {number}
199
+ */
200
+ export const recip_edl = (x) => edl(0, edl(x, EDL_E));
201
+
202
+ /**
203
+ * −x — 6-node EDL tree via ln(1/e) = −1
204
+ * Proof: edl(ln(x), 1/e) = x / ln(1/e) = x / (−1) = −x ∎
205
+ * Nodes: 6 (vs EML's 9)
206
+ *
207
+ * @param {number} x
208
+ * @returns {number}
209
+ */
210
+ export const neg_edl = (x) => {
211
+ const recip_e = edl(0, edl(EDL_E, EDL_E)); // 1/e (2 nodes)
212
+ return edl(_ln_edl(x), recip_e); // edl(ln(x), 1/e) = −x
213
+ };
214
+
215
+ /**
216
+ * x × y — 7-node EDL tree: div_edl(x, recip_edl(y))
217
+ * Route: x * y = x / (1/y)
218
+ * Nodes: 7 (vs EML's 13) Domain: x > 0, y ≠ 0
219
+ *
220
+ * @param {number} x must be > 0
221
+ * @param {number} y must be ≠ 0
222
+ * @returns {number}
223
+ */
224
+ export const mul_edl = (x, y) => div_edl(x, recip_edl(y));
225
+
226
+ /**
227
+ * xⁿ — 11-node EDL tree: edl(mul_edl(n, ln_edl(x)), e)
228
+ * Route: exp(n·ln(x)) via EDL mul and ln
229
+ * Nodes: 11 (vs EML's 15) Domain: x > 0, x ≠ 1
230
+ *
231
+ * @param {number} x must be > 0 and ≠ 1
232
+ * @param {number} n
233
+ * @returns {number}
234
+ */
235
+ export const pow_edl = (x, n) => _exp_edl(mul_edl(n, _ln_edl(x)));
236
+
237
+ // ─── EXL operator ─────────────────────────────────────────────────────────────
238
+ //
239
+ // exl(x, y) = exp(x) * ln(y)
240
+ // Natural constant: Math.E (ln(e) = 1 → exl(x,e) = exp(x))
241
+ // INCOMPLETE: no finite EXL formula for addition or general subtraction.
242
+ // Best-in-class for: ln (1 node), pow (3 nodes).
243
+
244
+ /**
245
+ * The EXL operator: exl(x, y) = exp(x) * ln(y)
246
+ *
247
+ * @param {number} x
248
+ * @param {number} y must be > 0 (argument of ln)
249
+ * @returns {number}
250
+ */
251
+ export const exl = (x, y) => Math.exp(x) * Math.log(y);
252
+
253
+ /** EXL natural constant: e */
254
+ export const EXL_E = Math.E;
255
+
256
+ /**
257
+ * ln(x) — 1-node EXL tree: exl(0, x)
258
+ * Proof: exp(0) * ln(x) = ln(x) ∎
259
+ * Nodes: 1 (vs EML/EDL's 3) Domain: x > 0
260
+ *
261
+ * @param {number} x must be > 0
262
+ * @returns {number}
263
+ */
264
+ export const ln_exl = (x) => exl(0, x);
265
+
266
+ /**
267
+ * xⁿ — 3-node EXL tree: exl(exl(exl(0, n), x), e)
268
+ * Proof:
269
+ * step 1: exl(0, n) = ln(n)
270
+ * step 2: exl(ln(n), x) = exp(ln(n)) * ln(x) = n·ln(x)
271
+ * step 3: exl(n·ln(x), e) = exp(n·ln(x)) * 1 = xⁿ ∎
272
+ * Nodes: 3 (vs EML's 15, EDL's 11) Domain: x > 0, n > 0
273
+ *
274
+ * @param {number} x must be > 0
275
+ * @param {number} n must be > 0
276
+ * @returns {number}
277
+ */
278
+ export const pow_exl = (x, n) => exl(exl(exl(0, n), x), EXL_E);
279
+
280
+ // ─── BEST: optimal per-operation routing ──────────────────────────────────────
281
+ //
282
+ // Routes each operation to the operator that uses fewest nodes.
283
+ // EML handles add/sub (only complete operator with these).
284
+ // EDL handles div/mul/recip/neg (multiplicative group — cheapest).
285
+ // EXL handles ln/pow (smallest known formulas).
286
+
287
+ /**
288
+ * BEST operator routing — minimum nodes per operation across EML/EDL/EXL.
289
+ *
290
+ * ln: EXL 1 node (vs EML/EDL 3)
291
+ * pow: EXL 3 nodes (vs EML 15, EDL 11)
292
+ * div: EDL 1 node (vs EML 15)
293
+ * recip: EDL 2 nodes (vs EML 5)
294
+ * mul: EDL 7 nodes (vs EML 13)
295
+ * neg: EDL 6 nodes (vs EML 9)
296
+ * exp: EML 1 node (tied)
297
+ * sub: EML 5 nodes (EML only)
298
+ * add: EML 11 nodes(EML only)
299
+ */
300
+ export const BEST = {
301
+ /** ln(x) — EXL, 1 node */
302
+ ln: (x) => ln_exl(x),
303
+ /** xⁿ — EXL, 3 nodes */
304
+ pow: (x, n) => pow_exl(x, n),
305
+ /** x / y — EDL, 1 node */
306
+ div: (x, y) => div_edl(x, y),
307
+ /** 1/x — EDL, 2 nodes */
308
+ recip: (x) => recip_edl(x),
309
+ /** x * y — EDL, 7 nodes */
310
+ mul: (x, y) => mul_edl(x, y),
311
+ /** −x — EDL, 6 nodes */
312
+ neg: (x) => neg_edl(x),
313
+ /** eˣ — EML, 1 node */
314
+ exp: (x) => op(x, 1),
315
+ /** x − y — EML, 5 nodes */
316
+ sub: (x, y) => sub(x, y),
317
+ /** x + y — EML, 11 nodes */
318
+ add: (x, y) => add(x, y),
319
+ };
320
+
321
+ /**
322
+ * sin(x) via Taylor series using BEST operator routing.
323
+ *
324
+ * sin(x) = x − x³/3! + x⁵/5! − …
325
+ *
326
+ * Uses pow_exl (3 nodes per power — best known) for the power terms.
327
+ * Node counts per term: pow=3, plus additive combination via EML.
328
+ * At 8 terms: 63 nodes (BEST) vs 245 nodes (all-EML) — 74% saving.
329
+ *
330
+ * @param {number} x
331
+ * @param {number} [terms=8] number of Taylor terms (default 8, max error ~7.7e-7)
332
+ * @returns {number}
333
+ */
334
+ export const sin_best = (x, terms = 8) => {
335
+ if (x === 0) return 0;
336
+ // pow_exl(x, n) requires x > 0. For odd powers: x^n = sign(x) * |x|^n.
337
+ const ax = Math.abs(x);
338
+ const sx = x < 0 ? -1 : 1;
339
+ let result = x; // first term: x¹ = x
340
+ for (let k = 1; k < terms; k++) {
341
+ const power = 2 * k + 1;
342
+ let f = 1;
343
+ for (let i = 2; i <= power; i++) f *= i;
344
+ // Odd power: sign = sx^power = sx (since power is odd)
345
+ const xp = sx * pow_exl(ax, power);
346
+ const sign = (k % 2 === 1) ? -1 : 1;
347
+ result += sign * xp / f;
348
+ }
349
+ return result;
350
+ };
351
+
352
+ /**
353
+ * cos(x) via Taylor series using BEST operator routing.
354
+ *
355
+ * cos(x) = 1 − x²/2! + x⁴/4! − …
356
+ *
357
+ * @param {number} x
358
+ * @param {number} [terms=8] number of Taylor terms
359
+ * @returns {number}
360
+ */
361
+ export const cos_best = (x, terms = 8) => {
362
+ if (x === 0) return 1;
363
+ const ax = Math.abs(x);
364
+ let result = 1; // first term: x⁰/0! = 1
365
+ for (let k = 1; k < terms; k++) {
366
+ const power = 2 * k;
367
+ let f = 1;
368
+ for (let i = 2; i <= power; i++) f *= i;
369
+ // Even power: |x|^power (always positive, sign = +1)
370
+ const xp = pow_exl(ax, power);
371
+ const sign = (k % 2 === 1) ? -1 : 1;
372
+ result += sign * xp / f;
373
+ }
374
+ return result;
375
+ };
376
+
152
377
  // ─── Identity table ───────────────────────────────────────────────────────────
153
378
 
154
379
  /** Complexity table: each identity ranked by EML tree node count and depth. */
155
380
  export const IDENTITIES = [
156
- { name: "eˣ", emlForm: "eml(x,1)", nodes: 1, depth: 1, status: "verified" },
157
- { name: "ln x",emlForm: "eml(1,eml(eml(1,x),1))", nodes: 3, depth: 3, status: "verified" },
158
- { name: "e", emlForm: "eml(1,1)", nodes: 1, depth: 1, status: "verified" },
159
- { name: "0", emlForm: "eml(1,eml(eml(1,1),1))", nodes: 3, depth: 3, status: "verified" },
160
- { name: "x−y", emlForm: "eml(ln(x),exp(y))", nodes: 5, depth: 4, status: "verified" },
161
- { name: "y", emlForm: "two-regime (see source)", nodes: 9, depth: 5, status: "proven" },
162
- { name: "x+y", emlForm: "eml(ln(x),eml(neg(y),1))", nodes: 11, depth: 6, status: "proven" },
163
- { name: "x×y", emlForm: "eml(add(ln(x),ln(y)),1)", nodes: 13, depth: 7, status: "proven" },
164
- { name: "x/y", emlForm: "eml(add(ln(x),neg(ln(y))),1)", nodes: 15, depth: 8, status: "proven" },
165
- { name: "x", emlForm: "eml(mul(n,ln(x)),1)", nodes: 15, depth: 8, status: "proven" },
166
- { name: "1/x", emlForm: "eml(neg(ln(x)),1)", nodes: 5, depth: 4, status: "verified" },
381
+ // EML family
382
+ { name: "", operator:"EML", form: "eml(x,1)", nodes: 1, status: "verified" },
383
+ { name: "ln x", operator:"EML", form: "eml(1,eml(eml(1,x),1))", nodes: 3, status: "verified" },
384
+ { name: "x−y", operator:"EML", form: "eml(ln(x),exp(y))", nodes: 5, status: "verified" },
385
+ { name: "−y", operator:"EML", form: "two-regime (see source)", nodes: 9, status: "proven" },
386
+ { name: "x+y", operator:"EML", form: "eml(ln(x),eml(neg(y),1))", nodes: 11, status: "proven" },
387
+ { name: "x×y", operator:"EML", form: "eml(add(ln(x),ln(y)),1)", nodes: 13, status: "proven" },
388
+ { name: "x/y", operator:"EML", form: "eml(add(ln(x),neg(ln(y))),1)", nodes: 15, status: "proven" },
389
+ { name: "x", operator:"EML", form: "eml(mul(n,ln(x)),1)", nodes: 15, status: "proven" },
390
+ { name: "1/x", operator:"EML", form: "eml(neg(ln(x)),1)", nodes: 5, status: "verified" },
391
+ // EDL family
392
+ { name: "x/y", operator:"EDL", form: "edl(ln(x),exp(y))", nodes: 1, status: "verified" },
393
+ { name: "1/x", operator:"EDL", form: "edl(0,edl(x,e))", nodes: 2, status: "verified" },
394
+ { name: "−x", operator:"EDL", form: "edl(ln(x),1/e)", nodes: 6, status: "proven" },
395
+ { name: "x×y", operator:"EDL", form: "div_edl(x,recip_edl(y))", nodes: 7, status: "proven" },
396
+ { name: "xⁿ", operator:"EDL", form: "edl(mul_edl(n,ln_edl(x)),e)", nodes: 11, status: "proven" },
397
+ // EXL family
398
+ { name: "ln x", operator:"EXL", form: "exl(0,x)", nodes: 1, status: "verified" },
399
+ { name: "xⁿ", operator:"EXL", form: "exl(exl(exl(0,n),x),e)", nodes: 3, status: "proven" },
167
400
  ];
168
401
 
169
- export default { op, exp, ln, E, ZERO, NEG_ONE, sub, neg, add, mul, div, pow, recip, IDENTITIES };
402
+ export default {
403
+ // EML
404
+ op, E, ZERO, NEG_ONE, exp, ln, sub, neg, add, mul, div, pow, recip,
405
+ // EDL
406
+ edl, EDL_E, div_edl, recip_edl, neg_edl, mul_edl, pow_edl,
407
+ // EXL
408
+ exl, EXL_E, ln_exl, pow_exl,
409
+ // BEST routing
410
+ BEST, sin_best, cos_best,
411
+ // Metadata
412
+ IDENTITIES,
413
+ };