eyeling 1.16.2 → 1.16.4

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 (51) hide show
  1. package/HANDBOOK.md +4 -0
  2. package/README.md +0 -1
  3. package/examples/ershov-mixed-computation.n3 +106 -0
  4. package/examples/output/ershov-mixed-computation.n3 +15 -0
  5. package/eyeling.js +510 -263
  6. package/lib/cli.js +22 -12
  7. package/lib/engine.js +488 -251
  8. package/package.json +2 -3
  9. package/arctifacts/README.md +0 -59
  10. package/arctifacts/ackermann.html +0 -678
  11. package/arctifacts/auroracare.html +0 -1297
  12. package/arctifacts/bike-trip.html +0 -752
  13. package/arctifacts/binomial-theorem.html +0 -631
  14. package/arctifacts/bmi.html +0 -511
  15. package/arctifacts/building-performance.html +0 -750
  16. package/arctifacts/clinical-care.html +0 -726
  17. package/arctifacts/collatz.html +0 -403
  18. package/arctifacts/complex.html +0 -321
  19. package/arctifacts/control-system.html +0 -482
  20. package/arctifacts/delfour.html +0 -849
  21. package/arctifacts/earthquake-epicenter.html +0 -982
  22. package/arctifacts/eco-route.html +0 -662
  23. package/arctifacts/euclid-infinitude.html +0 -564
  24. package/arctifacts/euler-identity.html +0 -667
  25. package/arctifacts/exoplanet-transit.html +0 -1000
  26. package/arctifacts/faltings-theorem.html +0 -1046
  27. package/arctifacts/fibonacci.html +0 -299
  28. package/arctifacts/fundamental-theorem-arithmetic.html +0 -398
  29. package/arctifacts/godel-numbering.html +0 -743
  30. package/arctifacts/gps-bike.html +0 -759
  31. package/arctifacts/gps-clinical-bench.html +0 -792
  32. package/arctifacts/graph-french.html +0 -449
  33. package/arctifacts/grass-molecular.html +0 -592
  34. package/arctifacts/group-theory.html +0 -740
  35. package/arctifacts/health-info.html +0 -833
  36. package/arctifacts/kaprekar-constant.html +0 -576
  37. package/arctifacts/lee.html +0 -805
  38. package/arctifacts/linked-lists.html +0 -502
  39. package/arctifacts/lldm.html +0 -612
  40. package/arctifacts/matrix-multiplication.html +0 -502
  41. package/arctifacts/matrix.html +0 -651
  42. package/arctifacts/newton-raphson.html +0 -944
  43. package/arctifacts/peano-factorial.html +0 -456
  44. package/arctifacts/pi.html +0 -363
  45. package/arctifacts/polynomial.html +0 -646
  46. package/arctifacts/prime.html +0 -366
  47. package/arctifacts/pythagorean-theorem.html +0 -468
  48. package/arctifacts/rest-path.html +0 -469
  49. package/arctifacts/roots-of-unity.html +0 -363
  50. package/arctifacts/turing.html +0 -409
  51. 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>