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,502 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <title>Matrix Multiplication • Not Commutative (AB ≠ BA)</title>
6
- <meta name="viewport" content="width=device-width, initial-scale=1" />
7
- <style>
8
- :root {
9
- --bg: #f7f8fb;
10
- --card: #ffffff;
11
- --ink: #0f172a;
12
- --muted: #4b5563;
13
- --accent: #2563eb;
14
- --ok: #059669;
15
- --bad: #b91c1c;
16
- --radius: 16px;
17
- --shadow: 0 10px 22px rgba(2, 6, 23, 0.06), 0 2px 6px rgba(2, 6, 23, 0.06);
18
- --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
19
- --sans: Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, 'Helvetica Neue', Arial;
20
- }
21
- * {
22
- box-sizing: border-box;
23
- }
24
- body {
25
- margin: 0;
26
- background: var(--bg);
27
- color: var(--ink);
28
- font: 16px/1.6 var(--sans);
29
- -webkit-font-smoothing: antialiased;
30
- }
31
- .wrap {
32
- max-width: 980px;
33
- margin: auto;
34
- padding: 28px 16px 64px;
35
- }
36
- header {
37
- display: flex;
38
- flex-direction: column;
39
- gap: 10px;
40
- margin-bottom: 22px;
41
- }
42
- h1 {
43
- font-size: clamp(24px, 3vw, 34px);
44
- line-height: 1.2;
45
- margin: 0;
46
- }
47
- .sub {
48
- color: var(--muted);
49
- }
50
- .pill {
51
- display: inline-flex;
52
- align-items: center;
53
- gap: 8px;
54
- background: #eef2ff;
55
- color: #3730a3;
56
- border-radius: 999px;
57
- padding: 8px 12px;
58
- font-weight: 600;
59
- font-size: 14px;
60
- width: max-content;
61
- }
62
- .grid {
63
- display: flex;
64
- flex-direction: column;
65
- gap: 16px;
66
- }
67
- .card {
68
- background: var(--card);
69
- border-radius: var(--radius);
70
- box-shadow: var(--shadow);
71
- padding: 18px;
72
- border: 1px solid #eef2f7;
73
- }
74
- .kicker {
75
- font-size: 12px;
76
- letter-spacing: 0.12em;
77
- text-transform: uppercase;
78
- color: #6b7280;
79
- }
80
- .muted {
81
- color: var(--muted);
82
- }
83
- .answer {
84
- font-size: 18px;
85
- font-weight: 800;
86
- }
87
- .ok {
88
- color: var(--ok);
89
- }
90
- .fail {
91
- color: var(--bad);
92
- font-weight: 800;
93
- }
94
- .result {
95
- margin-top: 10px;
96
- padding: 10px 12px;
97
- border-radius: 10px;
98
- background: #fafbff;
99
- border: 1px dashed #d7dbe5;
100
- }
101
- code,
102
- pre {
103
- font-family: var(--mono);
104
- }
105
- pre {
106
- background: #fafbff;
107
- color: #0f172a;
108
- padding: 14px;
109
- border-radius: 12px;
110
- white-space: pre-wrap;
111
- overflow-wrap: anywhere;
112
- word-break: break-word;
113
- overflow-x: hidden;
114
- overflow-y: auto;
115
- max-width: 100%;
116
- }
117
- .small {
118
- font-size: 13px;
119
- }
120
- textarea.input {
121
- width: 100%;
122
- min-height: 92px;
123
- padding: 10px 12px;
124
- border-radius: 10px;
125
- border: 1px solid #d9e1f1;
126
- background: #fdfefe;
127
- font-family: var(--mono);
128
- }
129
- .badge {
130
- display: inline-block;
131
- font-size: 12px;
132
- padding: 2px 8px;
133
- border-radius: 999px;
134
- background: #ecfeff;
135
- color: #155e75;
136
- border: 1px solid #a5f3fc;
137
- }
138
- .mat {
139
- display: inline-block;
140
- padding: 6px 10px;
141
- border: 1px solid #e5eaf3;
142
- border-radius: 10px;
143
- background: #fff;
144
- box-shadow: var(--shadow);
145
- font-family: var(--mono);
146
- }
147
- </style>
148
- </head>
149
- <body>
150
- <div class="wrap">
151
- <header>
152
- <h1>Matrix Multiplication • Not Commutative (AB ≠ BA)</h1>
153
- </header>
154
-
155
- <section class="grid">
156
- <!-- Problem statement -->
157
- <article class="card">
158
- <div class="kicker">Problem</div>
159
- <h2>Show there exist square matrices A,B with AB ≠ BA</h2>
160
- <p>We will use explicit 2×2 matrices and several independent checks.</p>
161
- <p class="small muted">
162
- Notation: matrices over ℤ (integers), standard matrix product. “Commutative” would require AB = BA for all
163
- A,B — which is false.
164
- </p>
165
- </article>
166
-
167
- <!-- Answer -->
168
- <article class="card">
169
- <div class="kicker">Answer</div>
170
- <p class="answer ok">
171
- Not commutative. A concrete counterexample is <span class="mat">A = [[1,2],[0,1]]</span> and
172
- <span class="mat">B = [[1,0],[3,1]]</span>, for which <span class="mat">AB = [[7,2],[3,1]]</span> but
173
- <span class="mat">BA = [[1,2],[3,7]]</span>, so AB ≠ BA.
174
- </p>
175
- </article>
176
-
177
- <!-- Reason Why -->
178
- <article class="card">
179
- <div class="kicker">Reason Why</div>
180
- <h2>Mathematical English justification</h2>
181
- <ol>
182
- <li>Take A = [[1, 2], [0, 1]] and B = [[1, 0], [3, 1]].</li>
183
- <li>Compute AB = [[1·1 + 2·3, 1·0 + 2·1], [0·1 + 1·3, 0·0 + 1·1]] = [[7, 2], [3, 1]].</li>
184
- <li>Compute BA = [[1·1 + 0·0, 1·2 + 0·1], [3·1 + 1·0, 3·2 + 1·1]] = [[1, 2], [3, 7]].</li>
185
- <li>
186
- Since AB ≠ BA, matrix multiplication is not commutative in general (a single counterexample suffices).
187
- </li>
188
- </ol>
189
- </article>
190
-
191
- <!-- Checks -->
192
- <article class="card" id="h1">
193
- <div class="kicker">Check (harness) #1</div>
194
- <h3>Counterexample computation</h3>
195
- <p class="small muted">Compute AB and BA for the fixed A,B above.</p>
196
- <div class="result" id="r1"></div>
197
- </article>
198
-
199
- <article class="card" id="h2">
200
- <div class="kicker">Check (harness) #2</div>
201
- <h3>Random 2×2 integer matrices</h3>
202
- <p class="small muted">
203
- Sample 300 random pairs with entries in −3..3 (not all zero). Report how many satisfy AB = BA.
204
- </p>
205
- <div class="result" id="r2"></div>
206
- </article>
207
-
208
- <article class="card" id="h3">
209
- <div class="kicker">Check (harness) #3</div>
210
- <h3>Exhaustive tiny space</h3>
211
- <p class="small muted">
212
- Enumerate all 2×2 matrices with entries in {0,1} (except both zero simultaneously for all entries) and count
213
- commuting pairs.
214
- </p>
215
- <div class="result" id="r3"></div>
216
- </article>
217
-
218
- <article class="card" id="h4">
219
- <div class="kicker">Check (harness) #4</div>
220
- <h3>Special cases that do commute</h3>
221
- <p class="small muted">
222
- Identity I, zero 0, and scalars λI commute with everything; diagonal matrices commute with each other.
223
- </p>
224
- <div class="result" id="r4"></div>
225
- </article>
226
-
227
- <article class="card" id="h5">
228
- <div class="kicker">Check (harness) #5</div>
229
- <h3>Commutator</h3>
230
- <p class="small muted">
231
- Compute [A,B]=AB-BA for the counterexample; nonzero commutator certifies non-commutativity.
232
- </p>
233
- <div class="result" id="r5"></div>
234
- </article>
235
-
236
- <article class="card" id="h6">
237
- <div class="kicker">Check (harness) #6</div>
238
- <h3>Your matrices (CSV)</h3>
239
- <p class="small muted">
240
- Paste A and B as four comma-separated rows each. Example:<br />
241
- <code>A: 1,2; 0,1</code><br /><code>B: 1,0; 3,1</code>
242
- </p>
243
- <textarea
244
- class="input"
245
- id="csv"
246
- placeholder="A: 1,2; 0,1
247
- B: 1,0; 3,1"></textarea>
248
- <div class="result" id="r6"></div>
249
- </article>
250
-
251
- <article class="card" id="h7">
252
- <div class="kicker">Check (harness) #7</div>
253
- <h3>Geometric intuition via shears</h3>
254
- <p class="small muted">
255
- Apply the two shears to a sample of points in both orders. The sets differ, showing the compositions differ.
256
- </p>
257
- <div class="result" id="r7"></div>
258
- </article>
259
- </section>
260
- </div>
261
-
262
- <script>
263
- // ---------- Matrix helpers ----------
264
- const mul = (A, B) => {
265
- const r = A.length,
266
- c = B[0].length,
267
- k = A[0].length;
268
- const C = Array.from({ length: r }, () => Array(c).fill(0));
269
- for (let i = 0; i < r; i++) {
270
- for (let j = 0; j < c; j++) {
271
- let s = 0;
272
- for (let t = 0; t < k; t++) s += A[i][t] * B[t][j];
273
- C[i][j] = s;
274
- }
275
- }
276
- return C;
277
- };
278
- const addM = (A, B) => A.map((row, i) => row.map((v, j) => v + B[i][j]));
279
- const subM = (A, B) => A.map((row, i) => row.map((v, j) => v - B[i][j]));
280
- const eqM = (A, B) =>
281
- A.length === B.length && A[0].length === B[0].length && A.every((row, i) => row.every((v, j) => v === B[i][j]));
282
- const fmt = (M) => `[${M.map((r) => '[' + r.join(', ') + ']').join(', ')}]`;
283
- const I2 = [
284
- [1, 0],
285
- [0, 1],
286
- ],
287
- Z2 = [
288
- [0, 0],
289
- [0, 0],
290
- ];
291
- const isDiag = (M) => M[0][1] === 0 && M[1][0] === 0;
292
-
293
- // Fixed counterexample (two shears)
294
- const A = [
295
- [1, 2],
296
- [0, 1],
297
- ];
298
- const B = [
299
- [1, 0],
300
- [3, 1],
301
- ];
302
-
303
- // ---------- Harness #1 ----------
304
- function check1() {
305
- const AB = mul(A, B),
306
- BA = mul(B, A);
307
- const pass = !eqM(AB, BA);
308
- const msg = `A = ${fmt(A)}\nB = ${fmt(B)}\nAB = ${fmt(AB)}\nBA = ${fmt(BA)}\nAB == BA ? ${eqM(AB, BA)}`;
309
- document.getElementById('r1').innerHTML =
310
- `<div class="${pass ? 'ok' : 'fail'}">${pass ? 'PASS' : 'FAIL'}</div><pre>${msg}</pre>`;
311
- }
312
-
313
- // ---------- Harness #2 ----------
314
- function randInt(a, b) {
315
- return a + Math.floor(Math.random() * (b - a + 1));
316
- }
317
- function randomMat() {
318
- return [
319
- [randInt(-3, 3), randInt(-3, 3)],
320
- [randInt(-3, 3), randInt(-3, 3)],
321
- ];
322
- }
323
- function isAllZero(M) {
324
- return M.every((r) => r.every((v) => v === 0));
325
- }
326
- function check2() {
327
- const trials = 300;
328
- let commute = 0,
329
- total = 0;
330
- for (let t = 0; t < trials; t++) {
331
- let A = randomMat(),
332
- B = randomMat();
333
- if (isAllZero(A) && isAllZero(B)) {
334
- t--;
335
- continue;
336
- }
337
- total++;
338
- if (eqM(mul(A, B), mul(B, A))) commute++;
339
- }
340
- const msg = `Random pairs tested: ${total}\nPairs with AB = BA: ${commute}\nPairs with AB ≠ BA: ${total - commute}`;
341
- const pass = total - commute > 0;
342
- document.getElementById('r2').innerHTML =
343
- `<div class="${pass ? 'ok' : 'fail'}">${pass ? 'PASS' : 'FAIL'}</div><pre>${msg}</pre>`;
344
- }
345
-
346
- // ---------- Harness #3 ----------
347
- function all01Mats() {
348
- // all 2x2 with entries in {0,1}
349
- const mats = [];
350
- for (let a = 0; a <= 1; a++)
351
- for (let b = 0; b <= 1; b++)
352
- for (let c = 0; c <= 1; c++)
353
- for (let d = 0; d <= 1; d++) {
354
- mats.push([
355
- [a, b],
356
- [c, d],
357
- ]);
358
- }
359
- return mats;
360
- }
361
- function check3() {
362
- const X = all01Mats();
363
- let commute = 0,
364
- total = 0;
365
- for (const M1 of X) {
366
- for (const M2 of X) {
367
- total++;
368
- if (eqM(mul(M1, M2), mul(M2, M1))) commute++;
369
- }
370
- }
371
- const msg = `Total ordered pairs (including identity & zero): ${total}\nCommuting pairs: ${commute}\nNon-commuting pairs: ${total - commute}`;
372
- const pass = total - commute > 0;
373
- document.getElementById('r3').innerHTML =
374
- `<div class="${pass ? 'ok' : 'fail'}">${pass ? 'PASS' : 'FAIL'}</div><pre>${msg}</pre>`;
375
- }
376
-
377
- // ---------- Harness #4 ----------
378
- function check4() {
379
- const lambda = 5;
380
- const S = [
381
- [2, 0],
382
- [0, 3],
383
- ]; // diagonal
384
- const T = [
385
- [7, 0],
386
- [0, -4],
387
- ]; // diagonal
388
- const cases = [
389
- { name: 'I commutes with A', ok: eqM(mul(I2, A), mul(A, I2)) },
390
- { name: '0 commutes with B', ok: eqM(mul(Z2, B), mul(B, Z2)) },
391
- {
392
- name: 'λI commutes with A',
393
- ok: eqM(
394
- mul(
395
- [
396
- [lambda, 0],
397
- [0, lambda],
398
- ],
399
- A,
400
- ),
401
- mul(A, [
402
- [lambda, 0],
403
- [0, lambda],
404
- ]),
405
- ),
406
- },
407
- { name: 'Diagonal S with diagonal T', ok: eqM(mul(S, T), mul(T, S)) },
408
- ];
409
- const pass = cases.every((c) => c.ok);
410
- const lines = cases.map((c) => `${c.name}: ${c.ok ? 'true' : 'false'}`);
411
- document.getElementById('r4').innerHTML =
412
- `<div class="${pass ? 'ok' : 'fail'}">${pass ? 'PASS' : 'FAIL'}</div><pre>${lines.join('\n')}</pre>`;
413
- }
414
-
415
- // ---------- Harness #5 ----------
416
- function check5() {
417
- const AB = mul(A, B),
418
- BA = mul(B, A);
419
- const comm = subM(AB, BA); // [A,B] = AB-BA
420
- const nz = !eqM(comm, [
421
- [0, 0],
422
- [0, 0],
423
- ]);
424
- const msg = `[A,B] = AB - BA = ${fmt(comm)}\nZero? ${!nz}`;
425
- document.getElementById('r5').innerHTML =
426
- `<div class="${nz ? 'ok' : 'fail'}">${nz ? 'PASS (nonzero commutator)' : 'FAIL'}</div><pre>${msg}</pre>`;
427
- }
428
-
429
- // ---------- Harness #6 ----------
430
- function parseCSVSpec(text) {
431
- // Expect: A: a,b; c,d\nB: e,f; g,h
432
- const get = (k) => {
433
- const m = (text || '').match(new RegExp(`^\\s*${k}\\s*:\\s*([^\\n]+)$`, 'mi'));
434
- if (!m) return null;
435
- const rows = m[1].split(';').map((s) => s.trim());
436
- const nums = rows.map((r) => r.split(',').map((x) => parseFloat(x.trim())));
437
- if (
438
- nums.length !== 2 ||
439
- nums[0].length !== 2 ||
440
- nums[1].length !== 2 ||
441
- nums.flat().some((x) => Number.isNaN(x))
442
- )
443
- return null;
444
- return nums;
445
- };
446
- return { A: get('A'), B: get('B') };
447
- }
448
- function check6() {
449
- const { A, B } = parseCSVSpec(document.getElementById('csv').value);
450
- if (!A || !B) {
451
- document.getElementById('r6').innerHTML =
452
- `<div class="fail">FAIL</div><pre>Could not parse. Example:\nA: 1,2; 0,1\nB: 1,0; 3,1</pre>`;
453
- return;
454
- }
455
- const AB = mul(A, B),
456
- BA = mul(B, A),
457
- same = eqM(AB, BA);
458
- const msg = `A = ${fmt(A)}\nB = ${fmt(B)}\nAB = ${fmt(AB)}\nBA = ${fmt(BA)}\nAB == BA ? ${same}`;
459
- document.getElementById('r6').innerHTML =
460
- `<div class="${!same ? 'ok' : 'fail'}">${!same ? 'PASS (non-commutative pair)' : 'Note: this pair commutes'}</div><pre>${msg}</pre>`;
461
- }
462
-
463
- // ---------- Harness #7 ----------
464
- function apply(M, v) {
465
- return [M[0][0] * v[0] + M[0][1] * v[1], M[1][0] * v[0] + M[1][1] * v[1]];
466
- }
467
- function check7() {
468
- // Use the shear pair on a few points
469
- const pts = [
470
- [1, 0],
471
- [0, 1],
472
- [1, 1],
473
- [2, -1],
474
- ];
475
- const firstAB = pts.map((p) => apply(mul(A, B), p));
476
- const firstBA = pts.map((p) => apply(mul(B, A), p));
477
- const sameSets = JSON.stringify(firstAB) === JSON.stringify(firstBA);
478
- const lines = ['Points (p), (AB)p, (BA)p:'];
479
- for (let i = 0; i < pts.length; i++) {
480
- lines.push(
481
- `${JSON.stringify(pts[i])} → (AB)p=${JSON.stringify(firstAB[i])} ; (BA)p=${JSON.stringify(firstBA[i])}`,
482
- );
483
- }
484
- document.getElementById('r7').innerHTML =
485
- `<div class="${!sameSets ? 'ok' : 'fail'}">${!sameSets ? 'PASS' : 'FAIL'}</div><pre>${lines.join('\n')}</pre>`;
486
- }
487
-
488
- // Autorun
489
- window.addEventListener('DOMContentLoaded', () => {
490
- const csv = document.getElementById('csv');
491
- if (csv && !csv.value.trim()) csv.value = 'A: 1,2; 0,1\nB: 1,0; 3,1';
492
- check1();
493
- check2();
494
- check3();
495
- check4();
496
- check5();
497
- check6();
498
- check7();
499
- });
500
- </script>
501
- </body>
502
- </html>