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,482 +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>Control System</title>
7
- <style>
8
- :root {
9
- --bg: #ffffff;
10
- --ink: #111827;
11
- --muted: #6b7280;
12
- --panel: #f8fafc;
13
- --border: #e5e7eb;
14
- --accent: #0ea5e9;
15
- --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace;
16
- --ui:
17
- system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'Apple Color Emoji',
18
- 'Segoe UI Emoji';
19
- }
20
- html,
21
- body {
22
- height: 100%;
23
- }
24
- body {
25
- margin: 0;
26
- background: var(--bg);
27
- color: var(--ink);
28
- font: 15px/1.55 var(--ui);
29
- }
30
- .wrap {
31
- max-width: 980px;
32
- margin: 36px auto;
33
- padding: 0 16px;
34
- }
35
- header {
36
- display: flex;
37
- align-items: center;
38
- justify-content: space-between;
39
- margin-bottom: 16px;
40
- }
41
- h1 {
42
- font-size: 22px;
43
- margin: 0;
44
- letter-spacing: 0.2px;
45
- }
46
- .pill {
47
- display: inline-flex;
48
- align-items: center;
49
- gap: 8px;
50
- padding: 6px 10px;
51
- border: 1px solid var(--border);
52
- border-radius: 999px;
53
- color: var(--muted);
54
- background: #fff;
55
- }
56
- .row {
57
- display: flex;
58
- flex-direction: column;
59
- gap: 16px;
60
- }
61
- .card {
62
- background: var(--panel);
63
- border: 1px solid var(--border);
64
- border-radius: 14px;
65
- overflow: hidden;
66
- }
67
- .head {
68
- display: flex;
69
- align-items: center;
70
- justify-content: space-between;
71
- padding: 10px 12px;
72
- border-bottom: 1px solid var(--border);
73
- }
74
- .head h2 {
75
- font-size: 13px;
76
- text-transform: uppercase;
77
- letter-spacing: 0.08em;
78
- color: var(--muted);
79
- margin: 0;
80
- }
81
- .body {
82
- padding: 12px;
83
- }
84
- pre {
85
- white-space: pre-wrap;
86
- background: #fff;
87
- border: 1px solid var(--border);
88
- border-radius: 10px;
89
- padding: 12px;
90
- overflow: auto;
91
- font-family: var(--mono);
92
- font-size: 13px;
93
- }
94
- button {
95
- all: unset;
96
- background: #fff;
97
- border: 1px solid var(--border);
98
- padding: 8px 12px;
99
- border-radius: 10px;
100
- cursor: pointer;
101
- }
102
- button:hover {
103
- border-color: #cbd5e1;
104
- }
105
- .small {
106
- color: var(--muted);
107
- text-decoration: none;
108
- }
109
- .accent {
110
- color: var(--accent);
111
- }
112
- /* ARC v2 (Cards) */
113
- .arc-grid {
114
- display: flex;
115
- flex-direction: column;
116
- gap: 12px;
117
- }
118
- .arc-card {
119
- background: #fff;
120
- border: 1px solid var(--border);
121
- border-radius: 14px;
122
- overflow: hidden;
123
- }
124
- .arc-card .ac-head {
125
- display: flex;
126
- align-items: center;
127
- gap: 8px;
128
- padding: 10px 12px;
129
- border-bottom: 1px solid var(--border);
130
- font-size: 12px;
131
- letter-spacing: 0.08em;
132
- text-transform: uppercase;
133
- color: var(--muted);
134
- }
135
- .arc-card .ac-body {
136
- padding: 12px;
137
- }
138
- .arc-card pre {
139
- margin: 0;
140
- white-space: pre-wrap;
141
- background: #fff;
142
- border: 1px solid #eef2f7;
143
- border-radius: 10px;
144
- padding: 10px;
145
- font-family: var(--mono);
146
- font-size: 13px;
147
- }
148
- .arc-card.answer {
149
- border-left: 4px solid #10b981;
150
- }
151
- .arc-card.reason {
152
- border-left: 4px solid #3b82f6;
153
- }
154
- .arc-card.check {
155
- border-left: 4px solid #f59e0b;
156
- }
157
- .toolbar {
158
- display: flex;
159
- gap: 8px;
160
- align-items: center;
161
- }
162
- </style>
163
- </head>
164
- <body>
165
- <div class="wrap">
166
- <header>
167
- <h1>Control System</h1>
168
- <div class="pill">Self‑contained • No deps</div>
169
- </header>
170
-
171
- <div class="card" style="margin-bottom: 16px">
172
- <div class="body">
173
- <p>
174
- <strong>What this is?</strong> A self‑contained, browser‑only <em>ARC harness</em> for a toy closed‑loop
175
- control system. It embeds a small set of measurable facts and computes two actuator commands with simple
176
- control laws. Everything runs on this page—no network and no external libraries.
177
- </p>
178
- <p>
179
- <strong>How to use it:</strong> Review the embedded facts, press <em>Run</em> to generate the analysis, and
180
- optionally export the ARC report. The output is organized as <em>Answer</em> (final values),
181
- <em>Reason why</em> (explanations), <em>Trace</em> (step‑by‑step derivations), and <em>Check</em> (a small
182
- harness that re‑derives the results and verifies identities).
183
- </p>
184
- <p class="small">
185
- This page is provided for reproducibility and documentation; it is not guidance for real‑world control
186
- design.
187
- </p>
188
- </div>
189
- </div>
190
-
191
- <div class="row">
192
- <div class="card">
193
- <div class="head">
194
- <h2>Facts (embedded)</h2>
195
- <a
196
- href="#"
197
- class="small"
198
- onclick="
199
- copyFacts();
200
- return false;
201
- "
202
- >Copy facts</a
203
- >
204
- </div>
205
- <div class="body">
206
- <div
207
- id="facts"
208
- style="
209
- font-family: var(--mono);
210
- font-size: 12px;
211
- background: #fff;
212
- border: 1px dashed var(--border);
213
- border-radius: 10px;
214
- padding: 10px;
215
- white-space: pre-wrap;
216
- "></div>
217
- <div style="margin-top: 10px; display: flex; gap: 8px; flex-wrap: wrap">
218
- <button onclick="run()">▶ Run</button>
219
- <a
220
- href="#"
221
- class="small"
222
- onclick="
223
- copyARC();
224
- return false;
225
- "
226
- >Copy ARC</a
227
- >
228
- </div>
229
- </div>
230
- </div>
231
-
232
- <div class="card">
233
- <div class="head">
234
- <h2>Trace</h2>
235
- <button onclick="downloadText('control_system_trace.txt', document.getElementById('trace').textContent)">
236
- ⬇ Export .txt
237
- </button>
238
- </div>
239
- <div class="body"><pre id="trace">(no run yet)</pre></div>
240
- </div>
241
-
242
- <div class="card">
243
- <div class="head">
244
- <h2>ARC Output</h2>
245
- <div class="toolbar">
246
- <button onclick="toggleArcStyle()" id="styleBtn">Style: Cards</button>
247
- <button onclick="downloadARC()">⬇ Export .txt</button>
248
- </div>
249
- </div>
250
- <div class="body">
251
- <div id="arc-cards" class="arc-grid">
252
- <div class="arc-card answer">
253
- <div class="ac-head">Answer</div>
254
- <div class="ac-body"><pre id="arc_ans">(no run yet)</pre></div>
255
- </div>
256
- <div class="arc-card reason">
257
- <div class="ac-head">Reason why</div>
258
- <div class="ac-body"><pre id="arc_reason">(no run yet)</pre></div>
259
- </div>
260
- <div class="arc-card check">
261
- <div class="ac-head">Check (harness)</div>
262
- <div class="ac-body"><pre id="arc_check">(no run yet)</pre></div>
263
- </div>
264
- </div>
265
- <pre id="arc" style="display: none">(no run yet)</pre>
266
- </div>
267
- </div>
268
- </div>
269
- </div>
270
-
271
- <script>
272
- // ---------------- Facts (embedded) ----------------
273
- const measurement1 = { input1: [6, 11], disturbance2: [45, 39] };
274
- const measurement2 = { input2: true };
275
- const measurement3 = { disturbance1: 35766 };
276
- const measurement4 = { output2: 24 };
277
- const observation1 = { state1: 80 };
278
- const observation2 = { state2: false };
279
- const observation3 = { state3: 22 };
280
- const target2 = { output2: 29 };
281
-
282
- function measurement10(I) {
283
- // PND feedback control
284
- const [M1, M2] = measurement1[I];
285
- if (M1 < M2) {
286
- const M3 = M2 - M1;
287
- return Math.sqrt(M3);
288
- } else {
289
- return M1;
290
- }
291
- }
292
-
293
- // ---------------- Control rules ----------------
294
- function control1_actuator1() {
295
- // control1(actuator1, C)
296
- const steps = [];
297
- const M1 = measurement10('input1');
298
- if (measurement2['input2'] !== true) throw new Error('input2 must be true');
299
- const D1 = Number(measurement3['disturbance1']);
300
- const C1 = M1 * 19.6;
301
- const C2 = Math.log(D1) / Math.log(10.0); // ≡ Math.log10(D1)
302
- const C = C1 - C2;
303
-
304
- steps.push(`[actuator1] M1 = measurement10(input1) = sqrt(11-6) = ${M1.toFixed(12)} (PND feedback control)`);
305
- steps.push(`[actuator1] C1 = M1 * 19.6 = ${C1.toFixed(12)} % proportional part`);
306
- steps.push(`[actuator1] C2 = log(D1)/log(10) = log(35766)/log(10) = ${C2.toFixed(12)} % compensation part`);
307
- steps.push(`[actuator1] C = C1 - C2 = ${C.toFixed(12)} % simple feedforward control`);
308
-
309
- return { actuator: 'actuator1', C, steps };
310
- }
311
-
312
- function control1_actuator2() {
313
- // control1(actuator2, C)
314
- const steps = [];
315
- const P3 = Number(observation3['state3']);
316
- const M4 = Number(measurement4['output2']);
317
- const T2 = Number(target2['output2']);
318
- const E = T2 - M4;
319
- const D = P3 - M4;
320
- const C1 = 5.8 * E;
321
- const N = 7.3 / E;
322
- const C2 = N * D;
323
- const C = C1 + C2;
324
-
325
- steps.push(`[actuator2] E = T2 - M4 = ${T2.toFixed(0)} - ${M4.toFixed(0)} = ${E.toFixed(12)} % error`);
326
- steps.push(
327
- `[actuator2] D = P3 - M4 = ${P3.toFixed(0)} - ${M4.toFixed(0)} = ${D.toFixed(12)} % differential error`,
328
- );
329
- steps.push(`[actuator2] C1 = 5.8 * E = 5.8*${E.toFixed(0)} = ${C1.toFixed(12)} % proportional part`);
330
- steps.push(`[actuator2] N = 7.3 / E = 7.3/${E.toFixed(0)} = ${N.toFixed(12)} % nonlinear factor`);
331
- steps.push(
332
- `[actuator2] C2 = N * D = ${N.toFixed(12)}*${D.toFixed(0)} = ${C2.toFixed(12)} % nonlinear differential part`,
333
- );
334
- steps.push(`[actuator2] C = C1 + C2 = ${C1.toFixed(12)} + ${C2.toFixed(12)} = ${C.toFixed(12)}`);
335
-
336
- return { actuator: 'actuator2', C, steps };
337
- }
338
-
339
- function control1_all() {
340
- return [control1_actuator1(), control1_actuator2()];
341
- }
342
-
343
- // ---------------- ARC printing ----------------
344
- function run() {
345
- const sols = control1_all();
346
-
347
- // ----- Answer / Reason / Check -----
348
- const A = [],
349
- R = [],
350
- C = [],
351
- T = [];
352
-
353
- // Answer
354
- for (const s of sols) {
355
- A.push(`control1(${s.actuator}, C) → C = ${s.C.toFixed(12)}`);
356
- }
357
-
358
- // Reason why (conceptual, short; details live in Trace)
359
- R.push('Two simple control laws produce actuator setpoints:');
360
- R.push(
361
- ' • actuator1 uses feedback (sqrt of difference) plus a proportional term and a log-based compensation, then subtracts the compensation.',
362
- );
363
- R.push(
364
- ' • actuator2 uses proportional-on-error plus a nonlinear differential part (7.3/E)×(P3−M4), then adds both.',
365
- );
366
- R.push('Values are computed from the embedded facts shown above.');
367
-
368
- // Trace: stitch both step lists
369
- for (const s of sols) for (const line of s.steps) T.push(line);
370
-
371
- // Check (harness)
372
- try {
373
- check_harness(sols);
374
- C.push('OK: derivations match the rules; identities and PND logic verified.');
375
- } catch (e) {
376
- C.push('FAILED: ' + e.message);
377
- }
378
-
379
- // Populate Trace
380
- document.getElementById('trace').textContent = T.join('\n');
381
-
382
- // Populate Cards
383
- document.getElementById('arc_ans').textContent = A.join('\n');
384
- document.getElementById('arc_reason').textContent = R.join('\n');
385
- document.getElementById('arc_check').textContent = C.join('\n');
386
-
387
- // Keep a combined plain-text for copy/export
388
- const combined = [
389
- 'Answer',
390
- '------',
391
- ...A,
392
- '',
393
- 'Reason why',
394
- '----------',
395
- ...R,
396
- '',
397
- 'Check (harness)',
398
- '---------------',
399
- ...C,
400
- ].join('\n');
401
- document.getElementById('arc').textContent = combined;
402
- }
403
-
404
- // ---------------- Harness ----------------
405
- function check_harness(solutions) {
406
- const eps = 1e-12;
407
- // PND feedback control checks
408
- if (Math.abs(measurement10('input1') - Math.sqrt(11 - 6)) >= eps)
409
- throw new Error("measurement10('input1') mismatch");
410
- if (Math.abs(measurement10('disturbance2') - 45.0) >= eps)
411
- throw new Error("measurement10('disturbance2') mismatch");
412
- // log identity
413
- const D1 = Number(measurement3['disturbance1']);
414
- if (Math.abs(Math.log(D1) / Math.log(10.0) - Math.log10(D1)) >= eps) throw new Error('log identity mismatch');
415
- // recompute C values
416
- const recomputed = {};
417
- recomputed['actuator1'] = measurement10('input1') * 19.6 - Math.log(D1) / Math.log(10.0);
418
- const E = target2['output2'] - measurement4['output2']; // 29-24 = 5
419
- const D = observation3['state3'] - measurement4['output2']; // 22-24 = -2
420
- recomputed['actuator2'] = 5.8 * E + (7.3 / E) * D;
421
- for (const s of solutions) {
422
- if (Math.abs(s.C - recomputed[s.actuator]) >= eps) throw new Error(`Mismatch for ${s.actuator}`);
423
- }
424
- }
425
-
426
- // ---------------- Pretty facts ----------------
427
- function showFacts() {
428
- const obj = {
429
- measurement1,
430
- measurement2,
431
- measurement3,
432
- measurement4,
433
- observation1,
434
- observation2,
435
- observation3,
436
- target2,
437
- };
438
- document.getElementById('facts').textContent = JSON.stringify(obj, null, 2);
439
- }
440
-
441
- // Utilities
442
- function downloadText(name, text) {
443
- const blob = new Blob([text], { type: 'text/plain' });
444
- const a = document.createElement('a');
445
- a.href = URL.createObjectURL(blob);
446
- a.download = name;
447
- document.body.appendChild(a);
448
- a.click();
449
- a.remove();
450
- }
451
- function copyARC() {
452
- navigator.clipboard.writeText(document.getElementById('arc').textContent);
453
- }
454
- function copyFacts() {
455
- navigator.clipboard.writeText(document.getElementById('facts').textContent);
456
- }
457
- function toggleArcStyle() {
458
- const pre = document.getElementById('arc');
459
- const cards = document.getElementById('arc-cards');
460
- const btn = document.getElementById('styleBtn');
461
- const showingCards = cards.style.display !== 'none';
462
- if (showingCards) {
463
- cards.style.display = 'none';
464
- pre.style.display = 'block';
465
- btn.textContent = 'Style: Plain';
466
- } else {
467
- cards.style.display = 'block';
468
- pre.style.display = 'none';
469
- btn.textContent = 'Style: Cards';
470
- }
471
- }
472
- function downloadARC() {
473
- const text = document.getElementById('arc').textContent;
474
- downloadText('control_system_arc.txt', text);
475
- }
476
-
477
- // bootstrap
478
- showFacts();
479
- run();
480
- </script>
481
- </body>
482
- </html>