eyeling 1.16.3 → 1.16.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 (61) hide show
  1. package/HANDBOOK.md +153 -0
  2. package/README.md +0 -1
  3. package/examples/auroracare.n3 +528 -0
  4. package/examples/control-system.n3 +223 -47
  5. package/examples/delfour.n3 +409 -0
  6. package/examples/gps.n3 +144 -53
  7. package/examples/ill-formed-literals.n3 +195 -0
  8. package/examples/output/auroracare.n3 +118 -0
  9. package/examples/output/control-system.n3 +24 -1
  10. package/examples/output/delfour.n3 +40 -0
  11. package/examples/output/gps.n3 +14 -2
  12. package/examples/output/ill-formed-literals.n3 +27 -0
  13. package/examples/output/parcellocker.n3 +15 -0
  14. package/examples/parcellocker.n3 +164 -0
  15. package/eyeling.js +16 -1
  16. package/lib/engine.js +14 -1
  17. package/lib/prelude.js +2 -0
  18. package/package.json +2 -3
  19. package/arctifacts/README.md +0 -59
  20. package/arctifacts/ackermann.html +0 -678
  21. package/arctifacts/auroracare.html +0 -1297
  22. package/arctifacts/bike-trip.html +0 -752
  23. package/arctifacts/binomial-theorem.html +0 -631
  24. package/arctifacts/bmi.html +0 -511
  25. package/arctifacts/building-performance.html +0 -750
  26. package/arctifacts/clinical-care.html +0 -726
  27. package/arctifacts/collatz.html +0 -403
  28. package/arctifacts/complex.html +0 -321
  29. package/arctifacts/control-system.html +0 -482
  30. package/arctifacts/delfour.html +0 -849
  31. package/arctifacts/earthquake-epicenter.html +0 -982
  32. package/arctifacts/eco-route.html +0 -662
  33. package/arctifacts/euclid-infinitude.html +0 -564
  34. package/arctifacts/euler-identity.html +0 -667
  35. package/arctifacts/exoplanet-transit.html +0 -1000
  36. package/arctifacts/faltings-theorem.html +0 -1046
  37. package/arctifacts/fibonacci.html +0 -299
  38. package/arctifacts/fundamental-theorem-arithmetic.html +0 -398
  39. package/arctifacts/godel-numbering.html +0 -743
  40. package/arctifacts/gps-bike.html +0 -759
  41. package/arctifacts/gps-clinical-bench.html +0 -792
  42. package/arctifacts/graph-french.html +0 -449
  43. package/arctifacts/grass-molecular.html +0 -592
  44. package/arctifacts/group-theory.html +0 -740
  45. package/arctifacts/health-info.html +0 -833
  46. package/arctifacts/kaprekar-constant.html +0 -576
  47. package/arctifacts/lee.html +0 -805
  48. package/arctifacts/linked-lists.html +0 -502
  49. package/arctifacts/lldm.html +0 -612
  50. package/arctifacts/matrix-multiplication.html +0 -502
  51. package/arctifacts/matrix.html +0 -651
  52. package/arctifacts/newton-raphson.html +0 -944
  53. package/arctifacts/peano-factorial.html +0 -456
  54. package/arctifacts/pi.html +0 -363
  55. package/arctifacts/polynomial.html +0 -646
  56. package/arctifacts/prime.html +0 -366
  57. package/arctifacts/pythagorean-theorem.html +0 -468
  58. package/arctifacts/rest-path.html +0 -469
  59. package/arctifacts/roots-of-unity.html +0 -363
  60. package/arctifacts/turing.html +0 -409
  61. package/arctifacts/wind-turbines.html +0 -726
@@ -1,678 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>A₂ (Ackermann via hyper-operations)</title>
7
- <style>
8
- :root {
9
- --fg: #101014;
10
- --bg: #ffffff;
11
- --muted: #666;
12
- --accent: #2563eb;
13
- --chip: #eef2ff;
14
- --ok: #16a34a;
15
- --bad: #dc2626;
16
- --warn: #ca8a04;
17
- }
18
- @media (prefers-color-scheme: dark) {
19
- :root {
20
- --fg: #eaeaf0;
21
- --bg: #0b0b10;
22
- --muted: #a0a0b0;
23
- --accent: #60a5fa;
24
- --chip: #0e1a32;
25
- }
26
- }
27
- html,
28
- body {
29
- margin: 0;
30
- padding: 0;
31
- background: var(--bg);
32
- color: var(--fg);
33
- font:
34
- 15px/1.6 ui-sans-serif,
35
- system-ui,
36
- -apple-system,
37
- Segoe UI,
38
- Roboto,
39
- Helvetica,
40
- Arial;
41
- }
42
- main {
43
- max-width: 1100px;
44
- margin: 0 auto;
45
- padding: 28px 16px 80px;
46
- }
47
- h1 {
48
- font-size: clamp(1.6rem, 2.6vw + 1rem, 2.2rem);
49
- margin: 0 0 6px;
50
- }
51
- header p {
52
- margin: 0;
53
- color: var(--muted);
54
- }
55
- section {
56
- margin: 18px 0 22px;
57
- padding: 14px 14px 16px;
58
- border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
59
- border-radius: 14px;
60
- background: color-mix(in srgb, var(--accent) 4%, transparent);
61
- }
62
- section h2 {
63
- margin: 0 0 8px;
64
- font-size: 1.15rem;
65
- }
66
- .row {
67
- display: flex;
68
- gap: 12px;
69
- align-items: center;
70
- flex-wrap: wrap;
71
- }
72
- .btn {
73
- appearance: none;
74
- border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
75
- background: color-mix(in srgb, var(--accent) 8%, transparent);
76
- color: var(--fg);
77
- border-radius: 10px;
78
- padding: 8px 12px;
79
- font-weight: 700;
80
- cursor: pointer;
81
- }
82
- .mono {
83
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;
84
- }
85
- .muted {
86
- color: var(--muted);
87
- }
88
- .small {
89
- font-size: 0.92em;
90
- }
91
- .chip {
92
- display: inline-block;
93
- padding: 2px 8px;
94
- border-radius: 999px;
95
- background: var(--chip);
96
- font-weight: 600;
97
- }
98
- input[type='number'] {
99
- width: 100px;
100
- border-radius: 10px;
101
- border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
102
- padding: 8px 10px;
103
- }
104
- label {
105
- user-select: none;
106
- }
107
- code {
108
- background: color-mix(in srgb, var(--accent) 10%, transparent);
109
- padding: 0.1rem 0.35rem;
110
- border-radius: 0.35rem;
111
- }
112
- details > summary {
113
- cursor: pointer;
114
- }
115
- .ok {
116
- color: var(--ok);
117
- }
118
- .bad {
119
- color: var(--bad);
120
- }
121
- .spinner {
122
- display: inline-block;
123
- width: 1em;
124
- height: 1em;
125
- border: 2px solid color-mix(in srgb, var(--accent) 30%, transparent);
126
- border-top-color: var(--accent);
127
- border-radius: 50%;
128
- animation: spin 1s linear infinite;
129
- vertical-align: middle;
130
- }
131
- @keyframes spin {
132
- to {
133
- transform: rotate(360deg);
134
- }
135
- }
136
-
137
- /* Ensure the Answer card can scroll horizontally for long lines */
138
- #answer {
139
- overflow-x: auto;
140
- }
141
- #answer pre {
142
- white-space: pre !important;
143
- overflow-x: auto;
144
- overflow-y: auto;
145
- max-width: 100%;
146
- }
147
- </style>
148
- </head>
149
- <body>
150
- <main>
151
- <header class="row">
152
- <div>
153
- <h1>A₂ (Ackermann via hyper-operations)</h1>
154
- </div>
155
- <div class="row" style="margin-left: auto">
156
- <label class="muted small">x: <input id="x" type="number" min="0" max="6" value="3" /></label>
157
- <label class="muted small">y: <input id="y" type="number" min="0" max="100000" value="4" /></label>
158
- <button id="compute" class="btn">Compute</button>
159
- <button id="demo" class="btn">Run demo set</button>
160
- </div>
161
- </header>
162
-
163
- <section>
164
- <h2>What this is?</h2>
165
- <p>This page mirrors the case file definition:</p>
166
- <p class="mono">A₂(x, y) = H(x, y+3, 2) − 3</p>
167
- <p class="small">
168
- with hyper‑operations <code>H</code> defined by <code>H(0,y,z)=y+1</code>, <code>H(1,y,z)=y+z</code>,
169
- <code>H(2,y,z)=y·z</code>, <code>H(x≥3,0,z)=1</code>, <code>H(x≥3,y>0,z)</code>: repeat <code>y</code> times
170
- <code>result = H(x−1, result, z)</code> starting from <code>1</code>. For <code>z=2</code>, this yields
171
- exponentiation for <code>x=3</code> and tetration for <code>x=4</code>.
172
- </p>
173
- </section>
174
-
175
- <section id="answer">
176
- <h2>Answer</h2>
177
- <div id="chips" class="row small" style="gap: 8px"></div>
178
- <div id="one"></div>
179
- <details id="demos">
180
- <summary>Demo queries (12)</summary>
181
- <div id="demosBody" class="mono small"></div>
182
- </details>
183
- </section>
184
-
185
- <section id="reason">
186
- <h2>Reason why</h2>
187
- <div class="small">
188
- <p>
189
- Closed forms: <code>A₂(0,y)=y+1</code>, <code>A₂(1,y)=y+2</code>, <code>A₂(2,y)=2y+3</code>,
190
- <code>A₂(3,y)=2^(y+3)−3</code>.
191
- </p>
192
- <p>
193
- For <code>x=4</code> we hit <code>2^^(y+3)</code>. When that’s still realistically printable (like
194
- <code>2^65536−3</code>), we expand it exactly using a background worker.
195
- </p>
196
- </div>
197
- </section>
198
-
199
- <section id="check">
200
- <h2>Check (harness)</h2>
201
- <div id="check-body"></div>
202
- </section>
203
- </main>
204
-
205
- <script>
206
- (function () {
207
- 'use strict';
208
- const $ = (id) => document.getElementById(id);
209
- const setHTML = (id, html) => {
210
- const el = $(id);
211
- if (el) el.innerHTML = html;
212
- };
213
- const now = () => performance.now();
214
-
215
- // ---------- Limits ----------
216
- const DECIMAL_LIMIT = 70000; // auto-expand if decimal digits <= this
217
-
218
- // ---------- Worker for heavy expansion ----------
219
- function createPow2Minus3Worker() {
220
- const code = `
221
- self.onmessage = function(e){
222
- const expStr = e.data && e.data.exp;
223
- try{
224
- const exp = BigInt(expStr);
225
- function pow2ExactExp(e){
226
- try { return (1n << e); }
227
- catch (_){
228
- // fallback to exponentiation by squaring
229
- let base = 2n, res = 1n, x = e;
230
- while (x > 0n){
231
- if (x & 1n) res *= base;
232
- x >>= 1n;
233
- if (x > 0n) base *= base;
234
- }
235
- return res;
236
- }
237
- }
238
- const t0 = Date.now();
239
- const val = pow2ExactExp(exp) - 3n;
240
- const s = val.toString();
241
- const t1 = Date.now();
242
- self.postMessage({ ok:true, digits: s.length, ms: t1 - t0, text: s });
243
- } catch(err){
244
- self.postMessage({ ok:false, error: (err && err.message) || String(err) });
245
- }
246
- };
247
- `;
248
- const blob = new Blob([code], { type: 'application/javascript' });
249
- return new Worker(URL.createObjectURL(blob));
250
- }
251
-
252
- // ---------- Representations ----------
253
- // {kind:'bigint', value: BigInt}
254
- // {kind:'pow2', exp: BigInt} // represents 2^exp
255
- // After A2: {kind:'pow2minus3', exp: BigInt}
256
-
257
- // Hyper-operations (z fixed to 2)
258
- function hyper2(x, y) {
259
- x = Number(x);
260
- y = Number(y);
261
- if (x === 0) return { kind: 'bigint', value: BigInt(y) + 1n };
262
- if (x === 1) return { kind: 'bigint', value: BigInt(y) + 2n };
263
- if (x === 2) return { kind: 'bigint', value: BigInt(y) * 2n };
264
- if (y === 0) return { kind: 'bigint', value: 1n };
265
- let result = { kind: 'bigint', value: 1n };
266
- for (let i = 0; i < y; i++) {
267
- if (x === 3) {
268
- result = { kind: 'bigint', value: result.kind === 'bigint' ? result.value * 2n : 1n << result.exp }; // safe for small
269
- } else if (x === 4) {
270
- if (result.kind === 'bigint') {
271
- const k = result.value;
272
- // If k is modest, compute 2^k exactly; otherwise keep symbolic
273
- if (k <= 4096n) {
274
- result = { kind: 'bigint', value: 1n << k };
275
- } else {
276
- result = { kind: 'pow2', exp: k };
277
- }
278
- } else {
279
- // result is already 2^k; next step would be astronomical; keep symbolic
280
- result = { kind: 'pow2', exp: result.exp > 4096n ? result.exp : 1n << result.exp };
281
- }
282
- } else {
283
- if (result.kind !== 'bigint') return result;
284
- result = hyper2(x - 1, Number(result.value));
285
- }
286
- }
287
- return result;
288
- }
289
-
290
- function A2_repr(x, y) {
291
- if (x < 0 || y < 0) throw new Error('x and y must be non-negative integers.');
292
- const h = hyper2(x, y + 3);
293
- if (h.kind === 'bigint') {
294
- return { kind: 'bigint', value: h.value - 3n };
295
- } else if (h.kind === 'pow2') {
296
- return { kind: 'pow2minus3', exp: h.exp };
297
- } else {
298
- return h;
299
- }
300
- }
301
-
302
- // ---------- Meta ----------
303
- function bitLengthBig(x) {
304
- return x.toString(2).length;
305
- }
306
- function digitsOfPow2(exp) {
307
- return Math.floor(Number(exp) * Math.LOG10E * Math.log(2)) + 1;
308
- }
309
- function chips(pairs) {
310
- return pairs
311
- .map(([k, v, cls]) => '<span class="chip ' + (cls || '') + '">' + k + ': ' + v + '</span>')
312
- .join(' ');
313
- }
314
-
315
- // ---------- Render one (uses worker if needed) ----------
316
- function renderOne(x, y) {
317
- const t0 = now();
318
- let rep,
319
- err = null;
320
- try {
321
- rep = A2_repr(x, y);
322
- } catch (e) {
323
- err = e.message || String(e);
324
- }
325
- const t1 = now();
326
- if (err) {
327
- setHTML('one', '<p class="bad">Error: ' + err + '</p>');
328
- return;
329
- }
330
-
331
- if (rep.kind === 'bigint') {
332
- const v = rep.value;
333
- const s = v.toString();
334
- const digits = s.length;
335
- const bits = bitLengthBig(v + 3n);
336
- setHTML(
337
- 'chips',
338
- chips([
339
- ['x', x],
340
- ['y', y],
341
- ['time', (t1 - t0).toFixed(2) + ' ms'],
342
- ['digits', digits],
343
- ['bit_length(A₂+3)', bits],
344
- ]),
345
- );
346
- setHTML(
347
- 'one',
348
- '<p><strong>A₂(' +
349
- x +
350
- ',' +
351
- y +
352
- ')</strong></p><pre class="mono" style="white-space:pre-wrap;overflow:auto">' +
353
- s +
354
- '</pre>',
355
- );
356
- } else if (rep.kind === 'pow2minus3') {
357
- const digits = digitsOfPow2(rep.exp);
358
- const bits = Number(rep.exp) + 1;
359
- if (digits <= DECIMAL_LIMIT) {
360
- // Expand in a worker so the UI stays responsive
361
- setHTML(
362
- 'chips',
363
- chips([
364
- ['x', x],
365
- ['y', y],
366
- ['time', (t1 - t0).toFixed(2) + ' ms'],
367
- ['digits', digits],
368
- ['bit_length(A₂+3)', bits],
369
- ]),
370
- );
371
- setHTML(
372
- 'one',
373
- '<p><strong>A₂(' +
374
- x +
375
- ',' +
376
- y +
377
- ')</strong> <span class="small muted"><span class="spinner"></span> expanding…</span></p>',
378
- );
379
- const w = createPow2Minus3Worker();
380
- w.onmessage = (ev) => {
381
- const d = ev.data || {};
382
- if (d.ok) {
383
- setHTML(
384
- 'chips',
385
- chips([
386
- ['x', x],
387
- ['y', y],
388
- ['time', (t1 - t0).toFixed(2) + ' ms'],
389
- ['expand', d.ms.toFixed ? d.ms.toFixed(1) + ' ms' : d.ms + ' ms'],
390
- ['digits', d.digits],
391
- ['bit_length(A₂+3)', bits],
392
- ]),
393
- );
394
- setHTML(
395
- 'one',
396
- '<p><strong>A₂(' +
397
- x +
398
- ',' +
399
- y +
400
- ')</strong></p><pre class="mono" style="white-space:pre-wrap;overflow:auto">' +
401
- d.text +
402
- '</pre>',
403
- );
404
- } else {
405
- setHTML(
406
- 'one',
407
- '<p class="bad">Expansion failed: ' +
408
- (d.error || 'unknown') +
409
- '</p><div class="small mono muted">A₂(' +
410
- x +
411
- ',' +
412
- y +
413
- ') = 2^(' +
414
- String(rep.exp) +
415
- ') − 3</div>',
416
- );
417
- }
418
- w.terminate();
419
- };
420
- w.postMessage({ exp: String(rep.exp) });
421
- } else {
422
- setHTML(
423
- 'chips',
424
- chips([
425
- ['x', x],
426
- ['y', y],
427
- ['time', (t1 - t0).toFixed(2) + ' ms'],
428
- ['digits', digits],
429
- ['bit_length(A₂+3)', bits],
430
- ]),
431
- );
432
- setHTML(
433
- 'one',
434
- '<p><strong>A₂(' +
435
- x +
436
- ',' +
437
- y +
438
- ')</strong> <em>(not expanded)</em></p><div class="small mono muted">A₂(' +
439
- x +
440
- ',' +
441
- y +
442
- ') = 2^(' +
443
- String(rep.exp) +
444
- ') − 3</div>',
445
- );
446
- }
447
- } else {
448
- setHTML('one', '<p class="bad">Unexpected representation.</p>');
449
- }
450
- }
451
-
452
- // ---------- Demo set (expand safe heavy case via worker) ----------
453
- const DEMO = [
454
- [0, 0],
455
- [0, 6],
456
- [1, 2],
457
- [1, 7],
458
- [2, 2],
459
- [2, 9],
460
- [3, 4],
461
- [3, 14],
462
- [4, 0],
463
- [4, 1],
464
- [4, 2],
465
- [5, 0],
466
- ];
467
-
468
- function runDemos() {
469
- const lines = new Array(DEMO.length);
470
- for (let i = 0; i < DEMO.length; i++) {
471
- const x = DEMO[i][0],
472
- y = DEMO[i][1];
473
- try {
474
- const rep = A2_repr(x, y);
475
- if (rep.kind === 'bigint') {
476
- const s = rep.value.toString();
477
- lines[i] =
478
- 'A' +
479
- String(i).padStart(2, '0') +
480
- ' = A₂(' +
481
- x +
482
- ',' +
483
- y +
484
- ') = ' +
485
- s +
486
- ' (digits=' +
487
- s.length +
488
- ')';
489
- } else if (rep.kind === 'pow2minus3') {
490
- const digits = digitsOfPow2(rep.exp);
491
- if (digits <= DECIMAL_LIMIT) {
492
- // placeholder; expand via worker
493
- lines[i] =
494
- 'A' +
495
- String(i).padStart(2, '0') +
496
- ' = A₂(' +
497
- x +
498
- ',' +
499
- y +
500
- ') = (expanding …) (digits≈' +
501
- digits +
502
- ')';
503
- // kick off worker for this line
504
- const w = createPow2Minus3Worker();
505
- ((idx, X, Y) => {
506
- w.onmessage = (ev) => {
507
- const d = ev.data || {};
508
- if (d.ok) {
509
- const s = d.text;
510
- lines[idx] =
511
- 'A' +
512
- String(idx).padStart(2, '0') +
513
- ' = A₂(' +
514
- X +
515
- ',' +
516
- Y +
517
- ') = ' +
518
- s +
519
- ' (digits=' +
520
- s.length +
521
- ')';
522
- } else {
523
- lines[idx] =
524
- 'A' +
525
- String(idx).padStart(2, '0') +
526
- ' = A₂(' +
527
- X +
528
- ',' +
529
- Y +
530
- ') = (expand failed) (digits≈' +
531
- digits +
532
- ')';
533
- }
534
- setHTML(
535
- 'demosBody',
536
- '<pre class="mono" style="white-space:pre-wrap">' + lines.join('\n') + '</pre>',
537
- );
538
- w.terminate();
539
- };
540
- })(i, x, y);
541
- w.postMessage({ exp: String(rep.exp) });
542
- } else {
543
- lines[i] =
544
- 'A' +
545
- String(i).padStart(2, '0') +
546
- ' = A₂(' +
547
- x +
548
- ',' +
549
- y +
550
- ') = (2^' +
551
- String(rep.exp) +
552
- ' − 3) (digits≈' +
553
- digits +
554
- ')';
555
- }
556
- } else {
557
- lines[i] = 'A' + String(i).padStart(2, '0') + ' = A₂(' + x + ',' + y + ') = [unexpected rep]';
558
- }
559
- } catch (e) {
560
- lines[i] =
561
- 'A' + String(i).padStart(2, '0') + ' = A₂(' + x + ',' + y + ') = [error: ' + (e.message || e) + ']';
562
- }
563
- }
564
- setHTML('demosBody', '<pre class="mono" style="white-space:pre-wrap">' + lines.join('\n') + '</pre>');
565
- $('demos').open = true;
566
- }
567
-
568
- // ---------- Check (unchanged from previous version) ----------
569
- function runChecks() {
570
- const lines = [];
571
- const ok = (b) => (b ? '✓' : '✗');
572
- const t0 = now();
573
- let okAll = true;
574
-
575
- // Closed forms
576
- let o = true;
577
- for (let y = 0; y <= 50; y++) {
578
- const r = A2_repr(0, y);
579
- if (r.kind !== 'bigint' || r.value !== BigInt(y) + 1n) {
580
- o = false;
581
- break;
582
- }
583
- }
584
- lines.push('A₂(0,y) = y+1 on y∈[0,50]? ' + ok(o));
585
- okAll = okAll && o;
586
-
587
- o = true;
588
- for (let y = 0; y <= 50; y++) {
589
- const r = A2_repr(1, y);
590
- if (r.kind !== 'bigint' || r.value !== BigInt(y) + 2n) {
591
- o = false;
592
- break;
593
- }
594
- }
595
- lines.push('A₂(1,y) = y+2 on y∈[0,50]? ' + ok(o));
596
- okAll = okAll && o;
597
-
598
- o = true;
599
- for (let y = 0; y <= 200; y++) {
600
- const r = A2_repr(2, y);
601
- if (r.kind !== 'bigint' || r.value !== 2n * BigInt(y) + 3n) {
602
- o = false;
603
- break;
604
- }
605
- }
606
- lines.push('A₂(2,y) = 2y+3 on y∈[0,200]? ' + ok(o));
607
- okAll = okAll && o;
608
-
609
- o = true;
610
- for (let y = 0; y <= 20; y++) {
611
- const r = A2_repr(3, y);
612
- const want = (1n << BigInt(y + 3)) - 3n;
613
- if (r.kind !== 'bigint' || r.value !== want) {
614
- o = false;
615
- break;
616
- }
617
- }
618
- lines.push('A₂(3,y) = 2^(y+3)−3 on y∈[0,20]? ' + ok(o));
619
- okAll = okAll && o;
620
-
621
- // Spot checks (11/12 exact)
622
- const expected = new Map([
623
- ['0,0', 1n],
624
- ['0,6', 7n],
625
- ['1,2', 4n],
626
- ['1,7', 9n],
627
- ['2,2', 7n],
628
- ['2,9', 21n],
629
- ['3,4', 125n],
630
- ['3,14', (1n << 17n) - 3n],
631
- ['4,0', 13n],
632
- ['4,1', 65533n],
633
- ['5,0', 65533n],
634
- ]);
635
- o = true;
636
- for (const [key, want] of expected) {
637
- const parts = key.split(',');
638
- const x = Number(parts[0]),
639
- y = Number(parts[1]);
640
- const r = A2_repr(x, y);
641
- if (r.kind !== 'bigint' || r.value !== want) {
642
- o = false;
643
- }
644
- }
645
- lines.push('Exact checks for 11/12 queries OK? ' + ok(o));
646
- okAll = okAll && o;
647
-
648
- // Big one handled symbolically in the rep (we expand later via worker if needed)
649
- const r = A2_repr(4, 2);
650
- const pass = r.kind === 'pow2minus3' && String(r.exp) === '65536';
651
- lines.push('A₂(4,2) handled as 2^65536−3 symbolically? ' + ok(pass));
652
- okAll = okAll && pass;
653
-
654
- const t1 = now();
655
- lines.push('');
656
- lines.push('All checks passed? ' + ok(okAll) + ' (' + (t1 - t0).toFixed(1) + ' ms)');
657
- const pre = document.createElement('pre');
658
- pre.className = 'mono';
659
- pre.style.whiteSpace = 'pre-wrap';
660
- pre.textContent = lines.join('\n');
661
- $('check-body').replaceChildren(pre);
662
- }
663
-
664
- // ---------- Wire up ----------
665
- $('compute').addEventListener('click', function () {
666
- const x = Math.max(0, Math.floor(Number($('x').value)));
667
- const y = Math.max(0, Math.floor(Number($('y').value)));
668
- renderOne(x, y);
669
- });
670
- $('demo').addEventListener('click', runDemos);
671
-
672
- // Initial
673
- renderOne(3, 4);
674
- runChecks();
675
- })();
676
- </script>
677
- </body>
678
- </html>