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.
- package/HANDBOOK.md +4 -0
- package/README.md +0 -1
- package/examples/ershov-mixed-computation.n3 +106 -0
- package/examples/output/ershov-mixed-computation.n3 +15 -0
- package/eyeling.js +510 -263
- package/lib/cli.js +22 -12
- package/lib/engine.js +488 -251
- package/package.json +2 -3
- package/arctifacts/README.md +0 -59
- package/arctifacts/ackermann.html +0 -678
- package/arctifacts/auroracare.html +0 -1297
- package/arctifacts/bike-trip.html +0 -752
- package/arctifacts/binomial-theorem.html +0 -631
- package/arctifacts/bmi.html +0 -511
- package/arctifacts/building-performance.html +0 -750
- package/arctifacts/clinical-care.html +0 -726
- package/arctifacts/collatz.html +0 -403
- package/arctifacts/complex.html +0 -321
- package/arctifacts/control-system.html +0 -482
- package/arctifacts/delfour.html +0 -849
- package/arctifacts/earthquake-epicenter.html +0 -982
- package/arctifacts/eco-route.html +0 -662
- package/arctifacts/euclid-infinitude.html +0 -564
- package/arctifacts/euler-identity.html +0 -667
- package/arctifacts/exoplanet-transit.html +0 -1000
- package/arctifacts/faltings-theorem.html +0 -1046
- package/arctifacts/fibonacci.html +0 -299
- package/arctifacts/fundamental-theorem-arithmetic.html +0 -398
- package/arctifacts/godel-numbering.html +0 -743
- package/arctifacts/gps-bike.html +0 -759
- package/arctifacts/gps-clinical-bench.html +0 -792
- package/arctifacts/graph-french.html +0 -449
- package/arctifacts/grass-molecular.html +0 -592
- package/arctifacts/group-theory.html +0 -740
- package/arctifacts/health-info.html +0 -833
- package/arctifacts/kaprekar-constant.html +0 -576
- package/arctifacts/lee.html +0 -805
- package/arctifacts/linked-lists.html +0 -502
- package/arctifacts/lldm.html +0 -612
- package/arctifacts/matrix-multiplication.html +0 -502
- package/arctifacts/matrix.html +0 -651
- package/arctifacts/newton-raphson.html +0 -944
- package/arctifacts/peano-factorial.html +0 -456
- package/arctifacts/pi.html +0 -363
- package/arctifacts/polynomial.html +0 -646
- package/arctifacts/prime.html +0 -366
- package/arctifacts/pythagorean-theorem.html +0 -468
- package/arctifacts/rest-path.html +0 -469
- package/arctifacts/roots-of-unity.html +0 -363
- package/arctifacts/turing.html +0 -409
- 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 & 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">->→→</span>,
|
|
303
|
-
<span class="mono"><->→↔</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>& → ∧</code>, <code>| → ∨</code>,
|
|
327
|
-
<code>-> → →</code>, <code><-> → ↔</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>
|