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,743 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <title>Gödel Numbering)</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: #475569;
13
- --ok: #067647;
14
- --bad: #b42318;
15
- --accent: #2563eb;
16
- --ring: #dbeafe;
17
- --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
18
- --sans:
19
- system-ui, -apple-system, Segoe UI, Roboto, Inter, 'Helvetica Neue', Arial, 'Noto Sans', 'Apple Color Emoji',
20
- 'Segoe UI Emoji';
21
- --radius: 14px;
22
- --shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 6px 20px rgba(0, 0, 0, 0.06);
23
- }
24
- * {
25
- box-sizing: border-box;
26
- }
27
- html,
28
- body {
29
- overflow-x: hidden;
30
- } /* remove any page-level horizontal scroll */
31
- body {
32
- margin: 0;
33
- color: var(--ink);
34
- background: var(--bg);
35
- font-family: var(--sans);
36
- line-height: 1.55;
37
- -webkit-font-smoothing: antialiased;
38
- }
39
- .wrap {
40
- max-width: 960px;
41
- margin: 28px auto;
42
- padding: 0 18px;
43
- display: flex;
44
- flex-direction: column;
45
- gap: 18px;
46
- }
47
- .title {
48
- font-size: clamp(24px, 3.8vw, 36px);
49
- font-weight: 800;
50
- letter-spacing: 0.2px;
51
- }
52
- .subtitle {
53
- color: var(--muted);
54
- }
55
- section.card {
56
- background: var(--card);
57
- border-radius: var(--radius);
58
- box-shadow: var(--shadow);
59
- padding: 18px 18px;
60
- display: flex;
61
- flex-direction: column;
62
- gap: 12px;
63
- border: 1px solid #eef2ff;
64
- }
65
- h2 {
66
- margin: 0;
67
- font-size: 20px;
68
- }
69
- h3 {
70
- margin: 0 0 6px 0;
71
- font-size: 16px;
72
- color: var(--muted);
73
- }
74
- code,
75
- kbd {
76
- font-family: var(--mono);
77
- }
78
- .pill {
79
- display: inline-flex;
80
- align-items: center;
81
- gap: 8px;
82
- background: #eef2ff;
83
- color: #1e40af;
84
- border: 1px solid #dbeafe;
85
- padding: 6px 10px;
86
- border-radius: 999px;
87
- font-size: 12px;
88
- font-weight: 600;
89
- }
90
- .grid {
91
- display: grid;
92
- gap: 10px;
93
- }
94
- .grid.cols-2 {
95
- grid-template-columns: 1fr;
96
- }
97
- .muted {
98
- color: var(--muted);
99
- }
100
- .mono {
101
- font-family: var(--mono);
102
- }
103
- textarea,
104
- input[type='text'] {
105
- width: 100%;
106
- border: 1px solid #e2e8f0;
107
- border-radius: 12px;
108
- padding: 10px 12px;
109
- background: #fff;
110
- font: 14px var(--mono);
111
- outline: none;
112
- }
113
- textarea:focus,
114
- input:focus {
115
- border-color: #bfdbfe;
116
- box-shadow: 0 0 0 6px var(--ring);
117
- }
118
- button {
119
- appearance: none;
120
- border: 1px solid #c7d2fe;
121
- background: #eef2ff;
122
- color: #1e3a8a;
123
- border-radius: 12px;
124
- padding: 10px 14px;
125
- font-weight: 700;
126
- cursor: pointer;
127
- }
128
- button:hover {
129
- background: #e0e7ff;
130
- }
131
- .answer {
132
- background: #f8fafc;
133
- color: #0f172a;
134
- padding: 12px;
135
- border-radius: 12px;
136
- border: 1px solid #e2e8f0;
137
- font: 14px var(--mono);
138
- overflow-y: hidden;
139
- overflow-x: hidden;
140
- white-space: pre-wrap;
141
- word-break: break-word;
142
- overflow-wrap: anywhere;
143
- }
144
- .kv {
145
- display: grid;
146
- grid-template-columns: 1fr;
147
- gap: 8px;
148
- align-items: start;
149
- }
150
- .tbl {
151
- border-collapse: collapse;
152
- width: 100%;
153
- }
154
- .tbl th,
155
- .tbl td {
156
- border: 1px solid #e2e8f0;
157
- padding: 6px 8px;
158
- font-size: 13px;
159
- vertical-align: top;
160
- word-break: break-word;
161
- overflow-wrap: anywhere;
162
- } /* wrap long integers */
163
- .tbl th {
164
- background: #f1f5f9;
165
- text-align: left;
166
- }
167
- .badge {
168
- font: 12px var(--mono);
169
- padding: 2px 6px;
170
- border-radius: 6px;
171
- border: 1px solid #e2e8f0;
172
- background: #fff;
173
- }
174
- .check {
175
- display: flex;
176
- flex-direction: column;
177
- gap: 8px;
178
- border-left: 4px solid #e2e8f0;
179
- padding-left: 12px;
180
- }
181
- .pass {
182
- color: var(--ok);
183
- }
184
- .fail {
185
- color: var(--bad);
186
- }
187
- .small {
188
- font-size: 12px;
189
- }
190
- .row {
191
- display: flex;
192
- gap: 10px;
193
- flex-wrap: wrap;
194
- align-items: center;
195
- }
196
- .caps {
197
- letter-spacing: 0.4px;
198
- text-transform: uppercase;
199
- font-weight: 800;
200
- font-size: 12px;
201
- color: #334155;
202
- }
203
- .copy {
204
- border: 1px dashed #94a3b8;
205
- background: #f8fafc;
206
- color: #334155;
207
- }
208
- .callout {
209
- padding: 10px 12px;
210
- background: #f8fafc;
211
- border: 1px solid #e2e8f0;
212
- border-radius: 12px;
213
- }
214
- .steps {
215
- counter-reset: step;
216
- display: flex;
217
- flex-direction: column;
218
- gap: 10px;
219
- }
220
- .steps p::before {
221
- counter-increment: step;
222
- content: counter(step) '. ';
223
- font-weight: 700;
224
- margin-right: 6px;
225
- }
226
- </style>
227
- </head>
228
- <body>
229
- <div class="wrap">
230
- <div>
231
- <div class="title">Gödel Numbering</div>
232
- </div>
233
-
234
- <!-- OVERVIEW / PROSE -->
235
- <section class="card">
236
- <h2>What this page does</h2>
237
- <p>
238
- This page demonstrates a classic Gödel numbering: each symbol in a logical formula is mapped to an integer
239
- code, shifted by <code>+1</code> to ensure positivity, and used as the exponent of successive primes
240
- <span class="mono">2, 3, 5, 7, …</span>. The product is the Gödel number ⟦ϕ⟧. Thanks to unique prime
241
- factorization, we can recover the exact formula from the number by reading those exponents back.
242
- </p>
243
- <div class="callout">
244
- <strong>How to use:</strong>
245
- Type a formula, click <em>Compute ⟦ϕ⟧</em> to see its number, or <em>Decode ⟦ϕ⟧</em> to reconstruct a formula
246
- from a number. The “Prime Exponent Decomposition” table shows the factorization of the last computed number.
247
- </div>
248
- </section>
249
-
250
- <!-- PROMPT / QUESTION -->
251
- <section class="card">
252
- <h2>Prompt &amp; Question</h2>
253
- <div class="muted">Teach the program a Gödel encoding scheme and answer:</div>
254
- <div class="kv">
255
- <div>
256
- <strong>Question.</strong> Compute the Gödel number ⟦ϕ⟧ for a given formula ϕ under the specified coding;
257
- also provide a “Reason Why” and run multiple “Check (harness)” tests.
258
- </div>
259
- <div><strong>Inputs.</strong> Data (alphabet & codes), Logic (encoding rules), and the formula ϕ.</div>
260
- </div>
261
- </section>
262
-
263
- <!-- DATA -->
264
- <section class="card">
265
- <h2>Data (Alphabet & Codes)</h2>
266
- <p class="muted">
267
- Reserved logic symbols have small codes; any other character uses a generic rule so everything remains
268
- encodable.
269
- </p>
270
- <div class="grid cols-2">
271
- <div>
272
- <h3>Reserved symbols</h3>
273
- <table class="tbl" id="codes-table">
274
- <thead>
275
- <tr>
276
- <th>Symbol</th>
277
- <th>Code c(·)</th>
278
- </tr>
279
- </thead>
280
- <tbody></tbody>
281
- </table>
282
- </div>
283
- <div>
284
- <h3>Generic rule</h3>
285
- <p>For any character <code>χ</code> not listed at left, use:</p>
286
- <p class="badge">c(χ) = 1000 + codePoint(χ)</p>
287
- <p>This guarantees a total, injective code over all Unicode symbols we might type.</p>
288
- <h3>Encoding function</h3>
289
- <p class="badge">E(χ) = c(χ) + 1</p>
290
- <p class="small muted">Adding 1 ensures exponents are ≥ 1 (we never use zero exponents).</p>
291
- </div>
292
- </div>
293
- </section>
294
-
295
- <!-- LOGIC -->
296
- <section class="card">
297
- <h2>Logic (Gödel Numbering)</h2>
298
- <div class="steps">
299
- <p>Let <span class="mono">p₁, p₂, …</span> be the increasing sequence of primes.</p>
300
- <p>
301
- Tokenize ϕ into <span class="mono">σ₁…σₙ</span> (normalize ASCII: <span class="mono">!→¬</span>,
302
- <span class="mono">&→∧</span>, <span class="mono">|→∨</span>, <span class="mono">-&gt;→→</span>,
303
- <span class="mono">&lt;-&gt;→↔</span>; ignore spaces).
304
- </p>
305
- <p>
306
- Define the Gödel number: <span class="badge">⟦σ₁…σₙ⟧ = ∏<sub>i=1..n</sub> pᵢ ^ E(σᵢ)</span>.
307
- </p>
308
- <p>
309
- Decoding: factor the number; the exponents are <span class="mono">E(σᵢ)=c(σᵢ)+1</span>. Subtract 1 and
310
- invert <span class="mono">c</span>.
311
- </p>
312
- </div>
313
- </section>
314
-
315
- <!-- PROGRAM / UI (VERTICAL STACK) -->
316
- <section class="card">
317
- <h2>Program</h2>
318
- <h3>Encode a formula</h3>
319
- <textarea id="input" rows="4" spellcheck="false">(∀x) (P(x) → Q(x))</textarea>
320
- <div class="row">
321
- <button id="encode">Compute ⟦ϕ⟧</button>
322
- <button id="decode">Decode ⟦ϕ⟧</button>
323
- <button id="copy" class="copy">Copy number</button>
324
- </div>
325
- <div class="small muted">
326
- ASCII synonyms allowed: <code>! → ¬</code>, <code>&amp; → ∧</code>, <code>| → ∨</code>,
327
- <code>-&gt; → →</code>, <code>&lt;-&gt; → ↔</code>. Spaces are ignored.
328
- </div>
329
-
330
- <h3>Answer</h3>
331
- <div class="answer" id="answer">Result will appear here…</div>
332
- </section>
333
-
334
- <!-- REASON WHY -->
335
- <section class="card">
336
- <h2>Reason Why (mathematical English)</h2>
337
- <p>
338
- Let ϕ have token sequence σ₁…σₙ. Define ⟦ϕ⟧ := ∏<sub>i=1..n</sub> pᵢ<sup>E(σᵢ)</sup>, where E(σ)=c(σ)+1 and
339
- c(·) is injective. By the Fundamental Theorem of Arithmetic, every natural number has a unique prime
340
- factorization. Hence the exponent vector (E(σ₁), …, E(σₙ)) is uniquely determined by ⟦ϕ⟧. Subtracting 1 yields
341
- (c(σ₁), …, c(σₙ)), and because c is injective we recover the exact σ₁…σₙ. Therefore ϕ ↦ ⟦ϕ⟧ is injective and
342
- decoding is well-defined.
343
- </p>
344
- <p class="callout">
345
- <strong>Compositionality.</strong> If τ is appended to ϕ, then ⟦ϕ·τ⟧ = ⟦ϕ⟧ · p<sub>n+1</sub><sup>E(τ)</sup>.
346
- This follows from multiplying by the next prime raised to the new symbol’s exponent.
347
- </p>
348
- </section>
349
-
350
- <!-- WORKED EXPLANATION -->
351
- <section class="card">
352
- <h2>Worked Example (reading the table)</h2>
353
- <p>
354
- After you click <em>Compute ⟦ϕ⟧</em>, the table below lists, for each position i, the i-th prime pᵢ, the
355
- corresponding exponent eᵢ, the recovered symbol, and its base code c(·) = eᵢ−1. Reading the symbols in order
356
- reconstructs the formula. If you change one symbol, only one exponent changes, so the product changes in
357
- exactly one prime component.
358
- </p>
359
- </section>
360
-
361
- <!-- EXPANSION / FACTORIZATION VIEW -->
362
- <section class="card">
363
- <h2>Prime Exponent Decomposition</h2>
364
- <div class="muted small">From the last computed Gödel number; exponents eᵢ satisfy eᵢ = E(σᵢ) = c(σᵢ)+1.</div>
365
- <table class="tbl" id="decomp">
366
- <thead>
367
- <tr>
368
- <th>#</th>
369
- <th>Prime pᵢ</th>
370
- <th>Exponent eᵢ</th>
371
- <th>Recovered symbol</th>
372
- <th>c(·)</th>
373
- </tr>
374
- </thead>
375
- <tbody></tbody>
376
- </table>
377
- </section>
378
-
379
- <!-- CHECKS -->
380
- <section class="card">
381
- <h2>Check (harness) 1</h2>
382
- <div class="check" id="check1"></div>
383
- </section>
384
- <section class="card">
385
- <h2>Check (harness) 2</h2>
386
- <div class="check" id="check2"></div>
387
- </section>
388
- <section class="card">
389
- <h2>Check (harness) 3</h2>
390
- <div class="check" id="check3"></div>
391
- </section>
392
- <section class="card">
393
- <h2>Check (harness) 4</h2>
394
- <div class="check" id="check4"></div>
395
- </section>
396
- <section class="card">
397
- <h2>Check (harness) 5</h2>
398
- <div class="check" id="check5"></div>
399
- </section>
400
- <section class="card">
401
- <h2>Check (harness) 6</h2>
402
- <div class="check" id="check6"></div>
403
- </section>
404
- <section class="card">
405
- <h2>Check (harness) 7</h2>
406
- <div class="check" id="check7"></div>
407
- </section>
408
- <section class="card">
409
- <h2>Check (harness) 8</h2>
410
- <div class="check" id="check8"></div>
411
- </section>
412
-
413
- <footer class="muted small" style="text-align: center; padding: 10px 0 20px 0">
414
- P3 pattern: Answer • Reason Why • Check. Gödel numbering demo. Vertical layout, light answer box, long-number
415
- wrapping.
416
- </footer>
417
- </div>
418
-
419
- <script>
420
- /* -------------------- DATA: reserved codes -------------------- */
421
- const RESERVED = new Map([
422
- ['¬', 1],
423
- ['∧', 2],
424
- ['∨', 3],
425
- ['→', 4],
426
- ['↔', 5],
427
- ['∀', 6],
428
- ['∃', 7],
429
- ['(', 8],
430
- [')', 9],
431
- [',', 10],
432
- ['=', 11],
433
- ['+', 12],
434
- ['·', 13],
435
- ['0', 14],
436
- ['1', 15],
437
- ]);
438
- // Build reverse map
439
- const REVERSE = new Map(Array.from(RESERVED, ([k, v]) => [v, k]));
440
-
441
- // Render reserved codes table
442
- (function renderCodes() {
443
- const tb = document.querySelector('#codes-table tbody');
444
- const rows = Array.from(
445
- RESERVED,
446
- ([sym, code]) => `<tr><td style="font-size:18px">${sym}</td><td>${code}</td></tr>`,
447
- ).join('');
448
- tb.innerHTML = rows;
449
- })();
450
-
451
- /* -------------------- HELPERS -------------------- */
452
- const asciiToUnicode = (s) =>
453
- s.replaceAll('<->', '↔').replaceAll('->', '→').replaceAll('!', '¬').replaceAll('&', '∧').replaceAll('|', '∨');
454
-
455
- function tokenize(str) {
456
- let s = asciiToUnicode(str).replace(/\s+/g, '');
457
- const tokens = [];
458
- for (let i = 0; i < s.length; ) {
459
- tokens.push(s[i]);
460
- i += 1;
461
- }
462
- return tokens.filter((t) => t && t.length > 0);
463
- }
464
-
465
- // Code function c(χ)
466
- function codeOf(sym) {
467
- if (RESERVED.has(sym)) return RESERVED.get(sym);
468
- // generic rule
469
- const cp = sym.codePointAt(0);
470
- return 1000 + cp;
471
- }
472
- // E(χ) = c(χ) + 1
473
- const E = (sym) => BigInt(codeOf(sym) + 1);
474
-
475
- // nth prime (1-indexed), BigInt
476
- const PRIMES = [2n]; // p1 = 2
477
- function isPrimeBI(n) {
478
- if (n < 2n) return false;
479
- for (const p of PRIMES) {
480
- if (p * p > n) break;
481
- if (n % p === 0n) return false;
482
- }
483
- return true;
484
- }
485
- function getPrime(i) {
486
- while (PRIMES.length < i) {
487
- let candidate = PRIMES[PRIMES.length - 1] + 1n;
488
- while (!isPrimeBI(candidate)) candidate += 1n;
489
- PRIMES.push(candidate);
490
- }
491
- return PRIMES[i - 1];
492
- }
493
- function powBI(a, e) {
494
- let base = BigInt(a),
495
- exp = BigInt(e),
496
- res = 1n;
497
- while (exp > 0n) {
498
- if (exp & 1n) res *= base;
499
- base *= base;
500
- exp >>= 1n;
501
- }
502
- return res;
503
- }
504
-
505
- // Encode
506
- function godelEncode(formula) {
507
- const toks = tokenize(formula);
508
- if (toks.length === 0) throw new Error('Empty formula has no Gödel number.');
509
- let G = 1n;
510
- toks.forEach((sym, idx) => {
511
- const p = getPrime(idx + 1); // p_i
512
- const e = E(sym); // exponent
513
- G *= powBI(p, e);
514
- });
515
- return { G, tokens: toks };
516
- }
517
-
518
- // Decode BigInt back to tokens
519
- function godelDecode(G_input) {
520
- let G = BigInt(G_input);
521
- if (G <= 0n) throw new Error('Gödel numbers are positive.');
522
- const exps = [];
523
- let i = 1;
524
- while (G > 1n) {
525
- const p = getPrime(i);
526
- let e = 0n;
527
- while (G % p === 0n) {
528
- G /= p;
529
- e += 1n;
530
- }
531
- if (e !== 0n) exps.push(e);
532
- i++;
533
- if (i > 10000) throw new Error('Aborted: suspiciously large factorization.');
534
- }
535
- const codes = exps.map((e) => Number(e - 1n));
536
- const syms = codes.map((c) => {
537
- if (REVERSE.has(c)) return REVERSE.get(c);
538
- if (c >= 1000) {
539
- const cp = c - 1000;
540
- return String.fromCodePoint(cp);
541
- }
542
- return '�';
543
- });
544
- return { tokens: syms, exponents: exps };
545
- }
546
-
547
- /* --------------- UI wiring --------------- */
548
- const $ = (sel) => document.querySelector(sel);
549
- const answerBox = $('#answer');
550
- const tableBody = $('#decomp tbody');
551
-
552
- function renderAnswer(G) {
553
- answerBox.textContent = String(G) + 'n';
554
- }
555
- function renderDecomp(G) {
556
- const { tokens, exponents } = godelDecode(G);
557
- tableBody.innerHTML = tokens
558
- .map((t, i) => {
559
- const p = getPrime(i + 1);
560
- const e = exponents[i];
561
- const c = codeOf(t);
562
- return `<tr>
563
- <td>${i + 1}</td>
564
- <td>${String(p)}</td>
565
- <td>${String(e)}</td>
566
- <td style="font-size:18px">${t}</td>
567
- <td>${c}</td>
568
- </tr>`;
569
- })
570
- .join('');
571
- }
572
-
573
- $('#encode').addEventListener('click', () => {
574
- try {
575
- const { G } = godelEncode($('#input').value);
576
- renderAnswer(G);
577
- renderDecomp(G);
578
- } catch (err) {
579
- answerBox.textContent = 'Error: ' + err.message;
580
- tableBody.innerHTML = '';
581
- }
582
- });
583
- $('#decode').addEventListener('click', () => {
584
- try {
585
- const text = prompt('Paste a Gödel number (BigInt, digits only):');
586
- if (!text) return;
587
- const G = BigInt(text);
588
- const { tokens } = godelDecode(G);
589
- $('#input').value = tokens.join('');
590
- renderAnswer(G);
591
- renderDecomp(G);
592
- } catch (err) {
593
- alert('Decode error: ' + err.message);
594
- }
595
- });
596
- $('#copy').addEventListener('click', async () => {
597
- try {
598
- const raw = answerBox.textContent.replace(/n$/, '');
599
- await navigator.clipboard.writeText(raw);
600
- $('#copy').textContent = 'Copied!';
601
- setTimeout(() => ($('#copy').textContent = 'Copy number'), 900);
602
- } catch {
603
- alert('Copy failed (permissions).');
604
- }
605
- });
606
-
607
- /* --------------- CHECKS --------------- */
608
- function normalize(s) {
609
- return tokenize(s).join('');
610
- }
611
- function checkCard(anchor, title, pass, detail) {
612
- anchor.innerHTML = `<div class="${pass ? 'pass' : 'fail'}"><strong>${pass ? 'PASS' : 'FAIL'}:</strong> ${title}</div>
613
- <div class="small muted">${detail}</div>`;
614
- }
615
-
616
- function runChecks() {
617
- const phi = '(∀x)(P(x) -> Q(x))';
618
- const psi = '(∃x)(P(x) & !Q(x))';
619
- const chi = '((P->Q)&(Q->R))->(P->R)';
620
-
621
- // 1. Round-trip ϕ
622
- try {
623
- const { G } = godelEncode(phi);
624
- const { tokens } = godelDecode(G);
625
- const ok = normalize(phi) === tokens.join('');
626
- checkCard(
627
- $('#check1'),
628
- 'ϕ encodes and decodes to itself.',
629
- ok,
630
- `ϕ = ${normalize(phi)}, decode = ${tokens.join('')}`,
631
- );
632
- } catch (e) {
633
- checkCard($('#check1'), 'ϕ encodes and decodes to itself.', false, e.message);
634
- }
635
-
636
- // 2. Round-trip ψ
637
- try {
638
- const { G } = godelEncode(psi);
639
- const { tokens } = godelDecode(G);
640
- const ok = normalize(psi) === tokens.join('');
641
- checkCard(
642
- $('#check2'),
643
- 'ψ encodes and decodes to itself.',
644
- ok,
645
- `ψ = ${normalize(psi)}, decode = ${tokens.join('')}`,
646
- );
647
- } catch (e) {
648
- checkCard($('#check2'), 'ψ encodes and decodes to itself.', false, e.message);
649
- }
650
-
651
- // 3. Distinctness
652
- try {
653
- const G1 = godelEncode(phi).G;
654
- const G2 = godelEncode(psi).G;
655
- const ok = G1 !== G2;
656
- checkCard($('#check3'), 'Distinct formulas map to distinct numbers.', ok, `⟦ϕ⟧ ${ok ? '≠' : '='} ⟦ψ⟧`);
657
- } catch (e) {
658
- checkCard($('#check3'), 'Distinct formulas map to distinct numbers.', false, e.message);
659
- }
660
-
661
- // 4. Append property
662
- try {
663
- const s = 'P';
664
- const t = 'Q';
665
- const encS = godelEncode(s);
666
- const encST = godelEncode(s + t);
667
- const pn1 = getPrime(encS.tokens.length + 1);
668
- const expected = encS.G * powBI(pn1, E(t));
669
- const ok = expected === encST.G;
670
- checkCard(
671
- $('#check4'),
672
- 'Appending a symbol multiplies by next prime’s power.',
673
- ok,
674
- `expected=${String(expected)}n`,
675
- );
676
- } catch (e) {
677
- checkCard($('#check4'), 'Appending a symbol multiplies by next prime’s power.', false, e.message);
678
- }
679
-
680
- // 5. Known exponents for "PQ"
681
- try {
682
- const enc = godelEncode('PQ');
683
- const { exponents } = godelDecode(enc.G);
684
- const cP = BigInt(codeOf('P') + 1),
685
- cQ = BigInt(codeOf('Q') + 1);
686
- const ok = exponents.length === 2 && exponents[0] === cP && exponents[1] === cQ;
687
- checkCard(
688
- $('#check5'),
689
- 'Exponent vector matches E(P), E(Q) for "PQ".',
690
- ok,
691
- `e₁=${String(exponents[0])}, e₂=${String(exponents[1])}`,
692
- );
693
- } catch (e) {
694
- checkCard($('#check5'), 'Exponent vector matches E(P), E(Q) for "PQ".', false, e.message);
695
- }
696
-
697
- // 6. Spaces ignored
698
- try {
699
- const g1 = godelEncode('P Q').G;
700
- const g2 = godelEncode('PQ').G;
701
- const ok = g1 === g2;
702
- checkCard($('#check6'), 'Whitespace does not affect encoding.', ok, `⟦\"P Q\"⟧ ${ok ? '=' : '≠'} ⟦\"PQ\"⟧`);
703
- } catch (e) {
704
- checkCard($('#check6'), 'Whitespace does not affect encoding.', false, e.message);
705
- }
706
-
707
- // 7. Complex χ
708
- try {
709
- const { G } = godelEncode(chi);
710
- const back = godelDecode(G).tokens.join('');
711
- const ok = normalize(chi) === back;
712
- checkCard($('#check7'), 'Complex χ encodes and decodes correctly.', ok, `len(tokens) = ${back.length}`);
713
- } catch (e) {
714
- checkCard($('#check7'), 'Complex χ encodes and decodes correctly.', false, e.message);
715
- }
716
-
717
- // 8. Empty input rejected
718
- try {
719
- let threw = false;
720
- try {
721
- godelEncode('');
722
- } catch {
723
- threw = true;
724
- }
725
- checkCard(
726
- $('#check8'),
727
- 'Empty input is invalid (guard rails).',
728
- threw,
729
- threw ? 'Properly rejected.' : 'Was not rejected.',
730
- );
731
- } catch (e) {
732
- checkCard($('#check8'), 'Empty input is invalid (guard rails).', false, e.message);
733
- }
734
- }
735
-
736
- // Initial compute and checks
737
- (function boot() {
738
- document.querySelector('#encode').click();
739
- runChecks();
740
- })();
741
- </script>
742
- </body>
743
- </html>