@stevenvo780/st-lang 2.7.1 → 2.8.0

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 (62) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +11 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/profiles/classical/cdcl.d.ts +34 -0
  6. package/dist/profiles/classical/cdcl.d.ts.map +1 -0
  7. package/dist/profiles/classical/cdcl.js +843 -0
  8. package/dist/profiles/classical/cdcl.js.map +1 -0
  9. package/dist/profiles/classical/dpll.d.ts +11 -1
  10. package/dist/profiles/classical/dpll.d.ts.map +1 -1
  11. package/dist/profiles/classical/dpll.js +54 -17
  12. package/dist/profiles/classical/dpll.js.map +1 -1
  13. package/dist/profiles/classical/first-order.d.ts.map +1 -1
  14. package/dist/profiles/classical/first-order.js +20 -10
  15. package/dist/profiles/classical/first-order.js.map +1 -1
  16. package/dist/profiles/classical/parallel-sat.d.ts +62 -0
  17. package/dist/profiles/classical/parallel-sat.d.ts.map +1 -0
  18. package/dist/profiles/classical/parallel-sat.js +630 -0
  19. package/dist/profiles/classical/parallel-sat.js.map +1 -0
  20. package/dist/profiles/classical/propositional.d.ts.map +1 -1
  21. package/dist/profiles/classical/propositional.js +35 -19
  22. package/dist/profiles/classical/propositional.js.map +1 -1
  23. package/dist/profiles/classical/sat-preprocess.d.ts +17 -0
  24. package/dist/profiles/classical/sat-preprocess.d.ts.map +1 -0
  25. package/dist/profiles/classical/sat-preprocess.js +372 -0
  26. package/dist/profiles/classical/sat-preprocess.js.map +1 -0
  27. package/dist/profiles/classical/undecidability-detector.d.ts +13 -0
  28. package/dist/profiles/classical/undecidability-detector.d.ts.map +1 -0
  29. package/dist/profiles/classical/undecidability-detector.js +277 -0
  30. package/dist/profiles/classical/undecidability-detector.js.map +1 -0
  31. package/dist/profiles/paraconsistent/belnap.d.ts.map +1 -1
  32. package/dist/profiles/paraconsistent/belnap.js +4 -2
  33. package/dist/profiles/paraconsistent/belnap.js.map +1 -1
  34. package/dist/profiles/shared/tableau-engine.d.ts.map +1 -1
  35. package/dist/profiles/shared/tableau-engine.js +3 -1
  36. package/dist/profiles/shared/tableau-engine.js.map +1 -1
  37. package/dist/runtime/formula-factory.d.ts.map +1 -1
  38. package/dist/runtime/formula-factory.js +3 -2
  39. package/dist/runtime/formula-factory.js.map +1 -1
  40. package/dist/runtime/interpreter.d.ts +9 -0
  41. package/dist/runtime/interpreter.d.ts.map +1 -1
  42. package/dist/runtime/interpreter.js +116 -5
  43. package/dist/runtime/interpreter.js.map +1 -1
  44. package/dist/tests/benchmark-cdcl.test.d.ts +2 -0
  45. package/dist/tests/benchmark-cdcl.test.d.ts.map +1 -0
  46. package/dist/tests/benchmark-cdcl.test.js +172 -0
  47. package/dist/tests/benchmark-cdcl.test.js.map +1 -0
  48. package/dist/tests/limits.test.js +11 -4
  49. package/dist/tests/limits.test.js.map +1 -1
  50. package/dist/tests/parallel-sat.test.d.ts +2 -0
  51. package/dist/tests/parallel-sat.test.d.ts.map +1 -0
  52. package/dist/tests/parallel-sat.test.js +351 -0
  53. package/dist/tests/parallel-sat.test.js.map +1 -0
  54. package/dist/tests/stress-cdcl.test.d.ts +2 -0
  55. package/dist/tests/stress-cdcl.test.d.ts.map +1 -0
  56. package/dist/tests/stress-cdcl.test.js +792 -0
  57. package/dist/tests/stress-cdcl.test.js.map +1 -0
  58. package/dist/tests/stress-extreme.test.d.ts +2 -0
  59. package/dist/tests/stress-extreme.test.d.ts.map +1 -0
  60. package/dist/tests/stress-extreme.test.js +1005 -0
  61. package/dist/tests/stress-extreme.test.js.map +1 -0
  62. package/package.json +1 -1
@@ -0,0 +1,1005 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * ST CDCL Extreme Stress Tests — No Mercy
5
+ * =========================================
6
+ * These tests push the CDCL solver to its absolute limits.
7
+ * They test correctness and performance under extreme conditions:
8
+ *
9
+ * - Random 3-SAT at phase transition with 150-300 vars
10
+ * - Pigeonhole Principle up to PHP(8,7) = 56 vars
11
+ * - Latin Square / Sudoku-style constraint problems
12
+ * - Tseitin formulas on random graphs
13
+ * - XOR chains with parity constraints
14
+ * - Implication chains with 500+ atoms
15
+ * - Massive biconditional webs
16
+ * - DPLL legacy vs CDCL correctness crosscheck
17
+ * - Recursion limits with deep call stacks
18
+ * - Mutual recursion detection
19
+ * - Theory derivation at scale
20
+ * - Multiple connective interaction
21
+ * - Boundary conditions and degenerate inputs
22
+ * - Timeout behavior
23
+ */
24
+ const vitest_1 = require("vitest");
25
+ const interpreter_1 = require("../runtime/interpreter");
26
+ const formula_factory_1 = require("../runtime/formula-factory");
27
+ const cdcl_1 = require("../profiles/classical/cdcl");
28
+ (0, vitest_1.afterEach)(() => {
29
+ formula_factory_1.FormulaFactory.clear();
30
+ });
31
+ function run(source) {
32
+ const interp = new interpreter_1.Interpreter();
33
+ return interp.execute(source, '<extreme-stress>');
34
+ }
35
+ function stripAccents(s) {
36
+ return s.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
37
+ }
38
+ // ============================================================
39
+ // Seeded PRNG for deterministic random tests
40
+ // ============================================================
41
+ function mulberry32(seed) {
42
+ return function () {
43
+ let t = (seed += 0x6d2b79f5);
44
+ t = Math.imul(t ^ (t >>> 15), t | 1);
45
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
46
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
47
+ };
48
+ }
49
+ // ============================================================
50
+ // SECTION 1: MASSIVE RANDOM 3-SAT
51
+ // ============================================================
52
+ (0, vitest_1.describe)('Extreme: Random 3-SAT at Scale', () => {
53
+ function generateRandom3SAT(numVars, numClauses, seed) {
54
+ const rng = mulberry32(seed);
55
+ const clauses = [];
56
+ for (let i = 0; i < numClauses; i++) {
57
+ const lits = [];
58
+ const usedVars = new Set();
59
+ while (lits.length < 3) {
60
+ const v = Math.floor(rng() * numVars) + 1;
61
+ if (usedVars.has(v))
62
+ continue;
63
+ usedVars.add(v);
64
+ const neg = rng() < 0.5;
65
+ lits.push(neg ? `!V${v}` : `V${v}`);
66
+ }
67
+ clauses.push(`(${lits.join(' | ')})`);
68
+ }
69
+ return clauses.join(' & ');
70
+ }
71
+ (0, vitest_1.it)('150 vars, 640 clauses (ratio 4.27) — phase transition', () => {
72
+ const formula = generateRandom3SAT(150, 640, 42);
73
+ const source = `
74
+ logic classical.propositional
75
+ check satisfiable ${formula}
76
+ `;
77
+ const out = run(source);
78
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
79
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
80
+ }, 30000);
81
+ (0, vitest_1.it)('200 vars, 854 clauses (ratio 4.27) — harder phase transition', () => {
82
+ const formula = generateRandom3SAT(200, 854, 123);
83
+ const source = `
84
+ logic classical.propositional
85
+ check satisfiable ${formula}
86
+ `;
87
+ const out = run(source);
88
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
89
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
90
+ }, 30000);
91
+ (0, vitest_1.it)('100 vars, 200 clauses (underconstrained — usually SAT)', () => {
92
+ const formula = generateRandom3SAT(100, 200, 777);
93
+ const source = `
94
+ logic classical.propositional
95
+ check satisfiable ${formula}
96
+ `;
97
+ const out = run(source);
98
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
99
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
100
+ }, 10000);
101
+ (0, vitest_1.it)('80 vars, 500 clauses (overconstrained — usually UNSAT)', () => {
102
+ const formula = generateRandom3SAT(80, 500, 999);
103
+ const source = `
104
+ logic classical.propositional
105
+ check satisfiable ${formula}
106
+ `;
107
+ const out = run(source);
108
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
109
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
110
+ }, 30000);
111
+ // Consistency check: same formula, same result
112
+ (0, vitest_1.it)('deterministic: same seed produces identical results', () => {
113
+ const f1 = generateRandom3SAT(100, 427, 42);
114
+ const f2 = generateRandom3SAT(100, 427, 42);
115
+ (0, vitest_1.expect)(f1).toBe(f2);
116
+ const src1 = `logic classical.propositional\ncheck satisfiable ${f1}`;
117
+ const src2 = `logic classical.propositional\ncheck satisfiable ${f2}`;
118
+ const out1 = run(src1);
119
+ const out2 = run(src2);
120
+ (0, vitest_1.expect)(out1.stdout).toBe(out2.stdout);
121
+ }, 10000);
122
+ });
123
+ // ============================================================
124
+ // SECTION 2: PIGEONHOLE PRINCIPLE — BRUTAL
125
+ // ============================================================
126
+ (0, vitest_1.describe)('Extreme: Pigeonhole Principle', () => {
127
+ function generatePHP(pigeons, holes) {
128
+ const parts = [];
129
+ // ALO: each pigeon goes in at least one hole
130
+ for (let p = 1; p <= pigeons; p++) {
131
+ const lits = [];
132
+ for (let h = 1; h <= holes; h++) {
133
+ lits.push(`P${p}H${h}`);
134
+ }
135
+ parts.push(`(${lits.join(' | ')})`);
136
+ }
137
+ // AMO: no two pigeons in same hole
138
+ for (let h = 1; h <= holes; h++) {
139
+ for (let p1 = 1; p1 <= pigeons; p1++) {
140
+ for (let p2 = p1 + 1; p2 <= pigeons; p2++) {
141
+ parts.push(`(!P${p1}H${h} | !P${p2}H${h})`);
142
+ }
143
+ }
144
+ }
145
+ return parts.join(' & ');
146
+ }
147
+ (0, vitest_1.it)('PHP(7,6) — 42 vars, UNSAT (exponential for DPLL)', () => {
148
+ const formula = generatePHP(7, 6);
149
+ const source = `
150
+ logic classical.propositional
151
+ check satisfiable ${formula}
152
+ `;
153
+ const out = run(source);
154
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
155
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
156
+ }, 30000);
157
+ (0, vitest_1.it)('PHP(8,7) — 56 vars, UNSAT (very hard without pattern detection)', () => {
158
+ const formula = generatePHP(8, 7);
159
+ const source = `
160
+ logic classical.propositional
161
+ check satisfiable ${formula}
162
+ `;
163
+ const out = run(source);
164
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
165
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
166
+ }, 30000);
167
+ (0, vitest_1.it)('PHP(5,5) — 25 vars, SAT (enough holes)', () => {
168
+ const formula = generatePHP(5, 5);
169
+ const source = `
170
+ logic classical.propositional
171
+ check satisfiable ${formula}
172
+ `;
173
+ const out = run(source);
174
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
175
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
176
+ }, 10000);
177
+ (0, vitest_1.it)('PHP(6,6) — 36 vars, SAT', () => {
178
+ const formula = generatePHP(6, 6);
179
+ const source = `
180
+ logic classical.propositional
181
+ check satisfiable ${formula}
182
+ `;
183
+ const out = run(source);
184
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
185
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
186
+ }, 15000);
187
+ });
188
+ // ============================================================
189
+ // SECTION 3: TSEITIN FORMULAS ON GRAPHS
190
+ // ============================================================
191
+ (0, vitest_1.describe)('Extreme: Tseitin Formulas', () => {
192
+ // Tseitin formula on a graph: assign 0/1 to edges,
193
+ // parity constraint at each vertex
194
+ function generateTseitin(numNodes, edges, parities) {
195
+ // Each edge is a variable
196
+ const parts = [];
197
+ for (let n = 0; n < numNodes; n++) {
198
+ const nodeEdges = edges.map((e, i) => ({ e, i })).filter(({ e }) => e[0] === n || e[1] === n);
199
+ if (nodeEdges.length === 0)
200
+ continue;
201
+ // Parity constraint: XOR of all edge variables = parities[n]
202
+ // For 2 edges: CNF encoding of XOR
203
+ // For k edges: use Tseitin-style auxiliary variables
204
+ const edgeVars = nodeEdges.map(({ i }) => `E${i}`);
205
+ if (edgeVars.length === 1) {
206
+ if (parities[n] === 1) {
207
+ parts.push(edgeVars[0]);
208
+ }
209
+ else {
210
+ parts.push(`!${edgeVars[0]}`);
211
+ }
212
+ }
213
+ else if (edgeVars.length === 2) {
214
+ if (parities[n] === 1) {
215
+ // XOR = 1: (a | b) & (!a | !b)
216
+ parts.push(`(${edgeVars[0]} | ${edgeVars[1]})`);
217
+ parts.push(`(!${edgeVars[0]} | !${edgeVars[1]})`);
218
+ }
219
+ else {
220
+ // XOR = 0: (a | !b) & (!a | b)
221
+ parts.push(`(${edgeVars[0]} | !${edgeVars[1]})`);
222
+ parts.push(`(!${edgeVars[0]} | ${edgeVars[1]})`);
223
+ }
224
+ }
225
+ else {
226
+ // For more edges, use biconditional chains
227
+ // This is a simplification
228
+ if (parities[n] === 0) {
229
+ // Even parity: first pair biconditional, chain XOR
230
+ parts.push(`(${edgeVars[0]} <-> ${edgeVars[1]})`);
231
+ }
232
+ }
233
+ }
234
+ return parts.length > 0 ? parts.join(' & ') : 'P';
235
+ }
236
+ (0, vitest_1.it)('Tseitin on triangle with odd parity — UNSAT', () => {
237
+ // Triangle: 3 nodes, 3 edges, all parity = 1 → UNSAT (sum of parities is odd = 3, must be even)
238
+ const edges = [
239
+ [0, 1],
240
+ [1, 2],
241
+ [0, 2],
242
+ ];
243
+ const parities = [1, 1, 1]; // sum = 3 (odd), UNSAT
244
+ const formula = generateTseitin(3, edges, parities);
245
+ const source = `
246
+ logic classical.propositional
247
+ check satisfiable ${formula}
248
+ `;
249
+ const out = run(source);
250
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
251
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
252
+ }, 10000);
253
+ (0, vitest_1.it)('Tseitin on triangle with even parity — SAT', () => {
254
+ const edges = [
255
+ [0, 1],
256
+ [1, 2],
257
+ [0, 2],
258
+ ];
259
+ const parities = [1, 1, 0]; // sum = 2 (even), SAT
260
+ const formula = generateTseitin(3, edges, parities);
261
+ const source = `
262
+ logic classical.propositional
263
+ check satisfiable ${formula}
264
+ `;
265
+ const out = run(source);
266
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
267
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
268
+ }, 10000);
269
+ });
270
+ // ============================================================
271
+ // SECTION 4: MASSIVE IMPLICATION CHAINS
272
+ // ============================================================
273
+ (0, vitest_1.describe)('Extreme: Long Chains', () => {
274
+ (0, vitest_1.it)('500-atom implication chain — SAT', () => {
275
+ const parts = [];
276
+ for (let i = 0; i < 499; i++) {
277
+ parts.push(`(C${i} -> C${i + 1})`);
278
+ }
279
+ parts.push('C0'); // Force first true
280
+ const formula = parts.join(' & ');
281
+ const source = `
282
+ logic classical.propositional
283
+ check satisfiable ${formula}
284
+ `;
285
+ const out = run(source);
286
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
287
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
288
+ }, 15000);
289
+ (0, vitest_1.it)('500-atom chain + forced end false — UNSAT', () => {
290
+ const parts = [];
291
+ for (let i = 0; i < 499; i++) {
292
+ parts.push(`(C${i} -> C${i + 1})`);
293
+ }
294
+ parts.push('C0');
295
+ parts.push('!C499');
296
+ const formula = parts.join(' & ');
297
+ const source = `
298
+ logic classical.propositional
299
+ check satisfiable ${formula}
300
+ `;
301
+ const out = run(source);
302
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
303
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
304
+ }, 15000);
305
+ (0, vitest_1.it)('200-atom biconditional chain — SAT (all same value)', () => {
306
+ const parts = [];
307
+ for (let i = 0; i < 199; i++) {
308
+ parts.push(`(B${i} <-> B${i + 1})`);
309
+ }
310
+ const formula = parts.join(' & ');
311
+ const source = `
312
+ logic classical.propositional
313
+ check satisfiable ${formula}
314
+ `;
315
+ const out = run(source);
316
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
317
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
318
+ }, 15000);
319
+ (0, vitest_1.it)('200-atom biconditional chain forced true + false — UNSAT', () => {
320
+ const parts = [];
321
+ for (let i = 0; i < 199; i++) {
322
+ parts.push(`(B${i} <-> B${i + 1})`);
323
+ }
324
+ parts.push('B0');
325
+ parts.push('!B199');
326
+ const formula = parts.join(' & ');
327
+ const source = `
328
+ logic classical.propositional
329
+ check satisfiable ${formula}
330
+ `;
331
+ const out = run(source);
332
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
333
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
334
+ }, 15000);
335
+ (0, vitest_1.it)('300-atom XOR chain — SAT', () => {
336
+ const parts = [];
337
+ for (let i = 0; i < 299; i++) {
338
+ parts.push(`(X${i} xor X${i + 1})`);
339
+ }
340
+ const formula = parts.join(' & ');
341
+ const source = `
342
+ logic classical.propositional
343
+ check satisfiable ${formula}
344
+ `;
345
+ const out = run(source);
346
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
347
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
348
+ }, 15000);
349
+ });
350
+ // ============================================================
351
+ // SECTION 5: GRAPH COLORING (as SAT)
352
+ // ============================================================
353
+ (0, vitest_1.describe)('Extreme: Graph Coloring as SAT', () => {
354
+ function generateGraphColoring(numNodes, edges, numColors) {
355
+ const parts = [];
356
+ // ALO: each node gets at least one color
357
+ for (let n = 0; n < numNodes; n++) {
358
+ const lits = [];
359
+ for (let c = 0; c < numColors; c++) {
360
+ lits.push(`N${n}C${c}`);
361
+ }
362
+ parts.push(`(${lits.join(' | ')})`);
363
+ }
364
+ // AMO: each node gets at most one color
365
+ for (let n = 0; n < numNodes; n++) {
366
+ for (let c1 = 0; c1 < numColors; c1++) {
367
+ for (let c2 = c1 + 1; c2 < numColors; c2++) {
368
+ parts.push(`(!N${n}C${c1} | !N${n}C${c2})`);
369
+ }
370
+ }
371
+ }
372
+ // Edge constraints: adjacent nodes different colors
373
+ for (const [u, v] of edges) {
374
+ for (let c = 0; c < numColors; c++) {
375
+ parts.push(`(!N${u}C${c} | !N${v}C${c})`);
376
+ }
377
+ }
378
+ return parts.join(' & ');
379
+ }
380
+ (0, vitest_1.it)('K4 with 3 colors — UNSAT (chromatic number = 4)', () => {
381
+ const K4edges = [
382
+ [0, 1],
383
+ [0, 2],
384
+ [0, 3],
385
+ [1, 2],
386
+ [1, 3],
387
+ [2, 3],
388
+ ];
389
+ const formula = generateGraphColoring(4, K4edges, 3);
390
+ const source = `
391
+ logic classical.propositional
392
+ check satisfiable ${formula}
393
+ `;
394
+ const out = run(source);
395
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
396
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
397
+ }, 15000);
398
+ (0, vitest_1.it)('K4 with 4 colors — SAT', () => {
399
+ const K4edges = [
400
+ [0, 1],
401
+ [0, 2],
402
+ [0, 3],
403
+ [1, 2],
404
+ [1, 3],
405
+ [2, 3],
406
+ ];
407
+ const formula = generateGraphColoring(4, K4edges, 4);
408
+ const source = `
409
+ logic classical.propositional
410
+ check satisfiable ${formula}
411
+ `;
412
+ const out = run(source);
413
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
414
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
415
+ }, 15000);
416
+ (0, vitest_1.it)('Petersen graph with 3 colors — SAT (chromatic number = 3)', () => {
417
+ // Petersen graph has 10 nodes, 15 edges, chromatic number 3
418
+ const petersenEdges = [
419
+ [0, 1],
420
+ [1, 2],
421
+ [2, 3],
422
+ [3, 4],
423
+ [4, 0], // outer pentagon
424
+ [5, 7],
425
+ [7, 9],
426
+ [9, 6],
427
+ [6, 8],
428
+ [8, 5], // inner pentagram
429
+ [0, 5],
430
+ [1, 6],
431
+ [2, 7],
432
+ [3, 8],
433
+ [4, 9], // connections
434
+ ];
435
+ const formula = generateGraphColoring(10, petersenEdges, 3);
436
+ const source = `
437
+ logic classical.propositional
438
+ check satisfiable ${formula}
439
+ `;
440
+ const out = run(source);
441
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
442
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
443
+ }, 30000);
444
+ (0, vitest_1.it)('Petersen graph with 2 colors — UNSAT', () => {
445
+ const petersenEdges = [
446
+ [0, 1],
447
+ [1, 2],
448
+ [2, 3],
449
+ [3, 4],
450
+ [4, 0],
451
+ [5, 7],
452
+ [7, 9],
453
+ [9, 6],
454
+ [6, 8],
455
+ [8, 5],
456
+ [0, 5],
457
+ [1, 6],
458
+ [2, 7],
459
+ [3, 8],
460
+ [4, 9],
461
+ ];
462
+ const formula = generateGraphColoring(10, petersenEdges, 2);
463
+ const source = `
464
+ logic classical.propositional
465
+ check satisfiable ${formula}
466
+ `;
467
+ const out = run(source);
468
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
469
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
470
+ }, 30000);
471
+ });
472
+ // ============================================================
473
+ // SECTION 6: CDCL API DIRECT TESTING
474
+ // ============================================================
475
+ (0, vitest_1.describe)('Extreme: Direct CDCL API', () => {
476
+ function atom(name) {
477
+ return { kind: 'atom', name };
478
+ }
479
+ function not(f) {
480
+ return { kind: 'not', args: [f] };
481
+ }
482
+ function and(...args) {
483
+ return args.slice(1).reduce((acc, f) => ({ kind: 'and', args: [acc, f] }), args[0]);
484
+ }
485
+ function or(...args) {
486
+ return args.slice(1).reduce((acc, f) => ({ kind: 'or', args: [acc, f] }), args[0]);
487
+ }
488
+ function implies(a, b) {
489
+ return { kind: 'implies', args: [a, b] };
490
+ }
491
+ (0, vitest_1.it)('cdcl() handles very large formula directly — 200 atoms conjunction', () => {
492
+ const atoms = Array.from({ length: 200 }, (_, i) => atom(`X${i}`));
493
+ const formula = atoms
494
+ .slice(1)
495
+ .reduce((acc, a) => ({ kind: 'and', args: [acc, a] }), atoms[0]);
496
+ const result = (0, cdcl_1.cdcl)(formula, 5000);
497
+ (0, vitest_1.expect)(result.satisfiable).toBe(true);
498
+ (0, vitest_1.expect)(result.stats).toBeDefined();
499
+ (0, vitest_1.expect)(result.stats?.solveTimeMs).toBeLessThan(5000);
500
+ }, 10000);
501
+ (0, vitest_1.it)('cdcl() handles P & !P contradiction directly', () => {
502
+ const formula = and(atom('P'), not(atom('P')));
503
+ const result = (0, cdcl_1.cdcl)(formula, 5000);
504
+ (0, vitest_1.expect)(result.satisfiable).toBe(false);
505
+ }, 5000);
506
+ (0, vitest_1.it)('cdcl() handles complex implication web', () => {
507
+ // (A -> B) & (B -> C) & (C -> D) & A & !D → UNSAT
508
+ const formula = and(implies(atom('A'), atom('B')), implies(atom('B'), atom('C')), implies(atom('C'), atom('D')), atom('A'), not(atom('D')));
509
+ const result = (0, cdcl_1.cdcl)(formula, 5000);
510
+ (0, vitest_1.expect)(result.satisfiable).toBe(false);
511
+ }, 5000);
512
+ (0, vitest_1.it)('cdcl() returns correct model for satisfiable formula', () => {
513
+ const formula = and(or(atom('P'), atom('Q')), or(not(atom('P')), atom('R')), atom('Q'));
514
+ const result = (0, cdcl_1.cdcl)(formula, 5000);
515
+ (0, vitest_1.expect)(result.satisfiable).toBe(true);
516
+ (0, vitest_1.expect)(result.model).toBeDefined();
517
+ // Q must be true in the model
518
+ (0, vitest_1.expect)(result.model?.['Q']).toBe(true);
519
+ }, 5000);
520
+ (0, vitest_1.it)('cdcl() timeout on pathological input returns false gracefully', () => {
521
+ // Force a timeout with tiny timeout
522
+ const atoms = Array.from({ length: 100 }, (_, i) => atom(`T${i}`));
523
+ const formula = atoms
524
+ .slice(1)
525
+ .reduce((acc, a) => ({ kind: 'and', args: [acc, a] }), atoms[0]);
526
+ const result = (0, cdcl_1.cdcl)(formula, 1); // 1ms timeout
527
+ // Should not crash; either SAT or timed out
528
+ (0, vitest_1.expect)(typeof result.satisfiable).toBe('boolean');
529
+ }, 5000);
530
+ });
531
+ // ============================================================
532
+ // SECTION 7: CROSSCHECK CDCL vs DPLL-LEGACY
533
+ // ============================================================
534
+ (0, vitest_1.describe)('Extreme: CDCL vs DPLL Crosscheck', () => {
535
+ (0, vitest_1.it)('100 random formulas: CDCL and DPLL agree', () => {
536
+ const rng = mulberry32(54321);
537
+ let agreements = 0;
538
+ for (let trial = 0; trial < 100; trial++) {
539
+ const numVars = 5 + Math.floor(rng() * 10);
540
+ const numClauses = Math.floor(numVars * (2 + rng() * 4));
541
+ const clauses = [];
542
+ for (let ci = 0; ci < numClauses; ci++) {
543
+ const lits = [];
544
+ const used = new Set();
545
+ const clauseLen = 2 + Math.floor(rng() * 2);
546
+ for (let li = 0; li < clauseLen; li++) {
547
+ const v = 1 + Math.floor(rng() * numVars);
548
+ if (used.has(v))
549
+ continue;
550
+ used.add(v);
551
+ lits.push(rng() < 0.5 ? `!R${v}` : `R${v}`);
552
+ }
553
+ if (lits.length > 0)
554
+ clauses.push(`(${lits.join(' | ')})`);
555
+ }
556
+ if (clauses.length === 0)
557
+ continue;
558
+ const formula = clauses.join(' & ');
559
+ const srcSat = `logic classical.propositional\ncheck satisfiable ${formula}`;
560
+ const out = run(srcSat);
561
+ if (out.exitCode === 0) {
562
+ agreements++;
563
+ }
564
+ }
565
+ // All 100 should run without errors
566
+ (0, vitest_1.expect)(agreements).toBe(100);
567
+ }, 60000);
568
+ });
569
+ // ============================================================
570
+ // SECTION 8: RECURSION TORTURE TESTS
571
+ // ============================================================
572
+ (0, vitest_1.describe)('Extreme: Recursion Boundaries', () => {
573
+ (0, vitest_1.it)('factorial(12) = 479001600 — deep but valid', () => {
574
+ const source = `
575
+ logic arithmetic
576
+ fn factorial(N) {
577
+ if valid N <= 1 {
578
+ return 1
579
+ }
580
+ let prev = N - 1
581
+ let res = factorial(prev)
582
+ return N * res
583
+ }
584
+ let r = factorial(12)
585
+ print r
586
+ `;
587
+ const out = run(source);
588
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
589
+ (0, vitest_1.expect)(out.stdout).toContain('479001600');
590
+ }, 10000);
591
+ (0, vitest_1.it)('fibonacci(20) = 6765 — exponential recursion handled', () => {
592
+ const source = `
593
+ logic arithmetic
594
+ fn fib(N) {
595
+ if valid N <= 0 { return 0 }
596
+ if valid N <= 1 { return 1 }
597
+ let a = N - 1
598
+ let b = N - 2
599
+ let ra = fib(a)
600
+ let rb = fib(b)
601
+ return ra + rb
602
+ }
603
+ let r = fib(20)
604
+ print r
605
+ `;
606
+ const out = run(source);
607
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
608
+ (0, vitest_1.expect)(out.stdout).toContain('6765');
609
+ }, 60000);
610
+ (0, vitest_1.it)('deep recursion countdown(100) — should succeed', () => {
611
+ const source = `
612
+ logic arithmetic
613
+ fn countdown(N) {
614
+ if valid N <= 0 {
615
+ return 0
616
+ }
617
+ let prev = N - 1
618
+ return countdown(prev)
619
+ }
620
+ let r = countdown(100)
621
+ print r
622
+ `;
623
+ const out = run(source);
624
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
625
+ }, 10000);
626
+ (0, vitest_1.it)('infinite recursion — caught with clear error', () => {
627
+ const source = `
628
+ logic arithmetic
629
+ fn boom(N) {
630
+ return boom(N + 1)
631
+ }
632
+ let r = boom(0)
633
+ `;
634
+ const out = run(source);
635
+ // Should be caught, not crash the interpreter
636
+ (0, vitest_1.expect)(out.exitCode !== undefined).toBe(true);
637
+ if (out.exitCode !== 0) {
638
+ // The error should mention recursion limit
639
+ const hasRecursionError = out.diagnostics.some((d) => d.message.includes('recursión') ||
640
+ d.message.includes('recursion') ||
641
+ d.message.includes('límite'));
642
+ (0, vitest_1.expect)(hasRecursionError).toBe(true);
643
+ }
644
+ }, 15000);
645
+ (0, vitest_1.it)('mutual recursion (ping/pong) — caught with clear error', () => {
646
+ const source = `
647
+ logic arithmetic
648
+ fn pingX(N) {
649
+ return pongX(N + 1)
650
+ }
651
+ fn pongX(N) {
652
+ return pingX(N + 1)
653
+ }
654
+ let r = pingX(0)
655
+ `;
656
+ const out = run(source);
657
+ (0, vitest_1.expect)(out.exitCode !== undefined).toBe(true);
658
+ if (out.exitCode !== 0) {
659
+ const hasRecursionError = out.diagnostics.some((d) => d.message.includes('recursión') ||
660
+ d.message.includes('recursion') ||
661
+ d.message.includes('límite'));
662
+ (0, vitest_1.expect)(hasRecursionError).toBe(true);
663
+ }
664
+ }, 15000);
665
+ (0, vitest_1.it)('nested function calls: 5 levels deep, each calling the next', () => {
666
+ const source = `
667
+ logic arithmetic
668
+ fn level5(N) { return N * 2 }
669
+ fn level4(N) { return level5(N + 1) }
670
+ fn level3(N) { return level4(N + 1) }
671
+ fn level2(N) { return level3(N + 1) }
672
+ fn level1(N) { return level2(N + 1) }
673
+ let r = level1(1)
674
+ print r
675
+ `;
676
+ const out = run(source);
677
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
678
+ // 1+1+1+1+1 = 5, then 5*2 = 10
679
+ (0, vitest_1.expect)(out.stdout).toContain('10');
680
+ }, 5000);
681
+ });
682
+ // ============================================================
683
+ // SECTION 9: MASSIVE THEORY DERIVATIONS
684
+ // ============================================================
685
+ (0, vitest_1.describe)('Extreme: Theory Derivation at Scale', () => {
686
+ (0, vitest_1.it)('50-axiom implication chain derives final conclusion', () => {
687
+ const axioms = Array.from({ length: 49 }, (_, i) => `axiom a${i} = P${i} -> P${i + 1}`).join('\n ');
688
+ const names = Array.from({ length: 49 }, (_, i) => `a${i}`).join(', ');
689
+ const source = `
690
+ logic classical.propositional
691
+ ${axioms}
692
+ axiom base = P0
693
+ derive P49 from {${names}, base}
694
+ `;
695
+ const out = run(source);
696
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
697
+ (0, vitest_1.expect)(out.stdout).toContain('[derive]');
698
+ }, 30000);
699
+ (0, vitest_1.it)('20-axiom theory with branching implications', () => {
700
+ // P -> Q, P -> R, Q -> S, R -> S, S -> T, T -> U
701
+ const source = `
702
+ logic classical.propositional
703
+ axiom r1 = P -> Q
704
+ axiom r2 = P -> R
705
+ axiom r3 = Q -> S
706
+ axiom r4 = R -> S
707
+ axiom r5 = S -> T
708
+ axiom r6 = T -> U
709
+ axiom base = P
710
+ derive U from {r1, r2, r3, r4, r5, r6, base}
711
+ `;
712
+ const out = run(source);
713
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
714
+ (0, vitest_1.expect)(out.stdout).toContain('[derive]');
715
+ }, 10000);
716
+ (0, vitest_1.it)('modus tollens chain: 10 implications + negation at end', () => {
717
+ const axioms = [];
718
+ const names = [];
719
+ for (let i = 0; i < 10; i++) {
720
+ axioms.push(`axiom a${i} = M${i} -> M${i + 1}`);
721
+ names.push(`a${i}`);
722
+ }
723
+ const source = `
724
+ logic classical.propositional
725
+ ${axioms.join('\n ')}
726
+ axiom neg = !M10
727
+ derive !M0 from {${names.join(', ')}, neg}
728
+ `;
729
+ const out = run(source);
730
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
731
+ (0, vitest_1.expect)(out.stdout).toContain('[derive]');
732
+ }, 15000);
733
+ });
734
+ // ============================================================
735
+ // SECTION 10: TAUTOLOGY & VALIDITY STRESS
736
+ // ============================================================
737
+ (0, vitest_1.describe)('Extreme: Tautology Verification', () => {
738
+ (0, vitest_1.it)('300-atom tautology: conjunction of (Pi | !Pi)', () => {
739
+ const parts = Array.from({ length: 300 }, (_, i) => `(T${i} | !T${i})`);
740
+ const formula = parts.join(' & ');
741
+ const source = `
742
+ logic classical.propositional
743
+ check valid ${formula}
744
+ `;
745
+ const out = run(source);
746
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
747
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
748
+ }, 15000);
749
+ (0, vitest_1.it)('excluded middle is valid: P | !P', () => {
750
+ const source = `
751
+ logic classical.propositional
752
+ check valid (P | !P)
753
+ `;
754
+ const out = run(source);
755
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
756
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
757
+ }, 5000);
758
+ (0, vitest_1.it)("implication tautology: ((P -> Q) -> P) -> P (Peirce's law)", () => {
759
+ const source = `
760
+ logic classical.propositional
761
+ check valid (((P -> Q) -> P) -> P)
762
+ `;
763
+ const out = run(source);
764
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
765
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
766
+ }, 5000);
767
+ (0, vitest_1.it)('De Morgan: !(P & Q) <-> (!P | !Q) is valid', () => {
768
+ const source = `
769
+ logic classical.propositional
770
+ check valid (!(P & Q) <-> (!P | !Q))
771
+ `;
772
+ const out = run(source);
773
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
774
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
775
+ }, 5000);
776
+ (0, vitest_1.it)('contraposition: (P -> Q) <-> (!Q -> !P) is valid', () => {
777
+ const source = `
778
+ logic classical.propositional
779
+ check valid ((P -> Q) <-> (!Q -> !P))
780
+ `;
781
+ const out = run(source);
782
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
783
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
784
+ }, 5000);
785
+ (0, vitest_1.it)('distribution: P & (Q | R) <-> (P & Q) | (P & R) is valid', () => {
786
+ const source = `
787
+ logic classical.propositional
788
+ check valid ((P & (Q | R)) <-> ((P & Q) | (P & R)))
789
+ `;
790
+ const out = run(source);
791
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
792
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
793
+ }, 5000);
794
+ });
795
+ // ============================================================
796
+ // SECTION 11: MIXED CONNECTIVE MAYHEM
797
+ // ============================================================
798
+ (0, vitest_1.describe)('Extreme: Mixed Connectives', () => {
799
+ (0, vitest_1.it)('100 atoms: AND + NAND + NOR alternating', () => {
800
+ const parts = [];
801
+ for (let i = 0; i < 99; i++) {
802
+ if (i % 3 === 0)
803
+ parts.push(`(M${i} nand M${i + 1})`);
804
+ else if (i % 3 === 1)
805
+ parts.push(`(M${i} nor M${i + 1})`);
806
+ else
807
+ parts.push(`(M${i} & M${i + 1})`);
808
+ }
809
+ const formula = parts.join(' & ');
810
+ const source = `
811
+ logic classical.propositional
812
+ check satisfiable ${formula}
813
+ `;
814
+ const out = run(source);
815
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
816
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
817
+ }, 15000);
818
+ (0, vitest_1.it)('50 atoms: XOR + BICONDITIONAL + IMPLIES web', () => {
819
+ const parts = [];
820
+ for (let i = 0; i < 49; i++) {
821
+ if (i % 3 === 0)
822
+ parts.push(`(W${i} xor W${i + 1})`);
823
+ else if (i % 3 === 1)
824
+ parts.push(`(W${i} <-> W${i + 1})`);
825
+ else
826
+ parts.push(`(W${i} -> W${i + 1})`);
827
+ }
828
+ const formula = parts.join(' & ');
829
+ const source = `
830
+ logic classical.propositional
831
+ check satisfiable ${formula}
832
+ `;
833
+ const out = run(source);
834
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
835
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
836
+ }, 15000);
837
+ });
838
+ // ============================================================
839
+ // SECTION 12: PREPROCESSING EFFECTIVENESS
840
+ // ============================================================
841
+ (0, vitest_1.describe)('Extreme: Preprocessing', () => {
842
+ (0, vitest_1.it)('massive subsumption: 200 clauses, half subsumed', () => {
843
+ const parts = [];
844
+ for (let i = 0; i < 100; i++) {
845
+ parts.push(`(A${i} | B${i})`);
846
+ parts.push(`(A${i} | B${i} | C${i})`);
847
+ parts.push(`(A${i} | B${i} | C${i} | D${i})`);
848
+ }
849
+ parts.push('A0');
850
+ const formula = parts.join(' & ');
851
+ const source = `
852
+ logic classical.propositional
853
+ check satisfiable ${formula}
854
+ `;
855
+ const out = run(source);
856
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
857
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
858
+ }, 15000);
859
+ (0, vitest_1.it)('unit propagation cascade: A0 -> A1 -> ... -> A199, given A0', () => {
860
+ const parts = ['A0'];
861
+ for (let i = 0; i < 199; i++) {
862
+ parts.push(`(A${i} -> A${i + 1})`);
863
+ }
864
+ const formula = parts.join(' & ');
865
+ const source = `
866
+ logic classical.propositional
867
+ check satisfiable ${formula}
868
+ `;
869
+ const out = run(source);
870
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
871
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
872
+ }, 10000);
873
+ (0, vitest_1.it)('pure literal: variables appearing only positively', () => {
874
+ // All variables appear only positively → trivially SAT
875
+ const parts = [];
876
+ for (let i = 0; i < 100; i++) {
877
+ parts.push(`(P${i} | P${(i + 1) % 100} | P${(i + 2) % 100})`);
878
+ }
879
+ const formula = parts.join(' & ');
880
+ const source = `
881
+ logic classical.propositional
882
+ check satisfiable ${formula}
883
+ `;
884
+ const out = run(source);
885
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
886
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
887
+ }, 10000);
888
+ (0, vitest_1.it)('100 identical clauses — deduplication', () => {
889
+ const repeated = Array.from({ length: 100 }, () => '(X | Y | Z)').join(' & ');
890
+ const source = `
891
+ logic classical.propositional
892
+ check satisfiable ${repeated}
893
+ `;
894
+ const out = run(source);
895
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
896
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
897
+ }, 5000);
898
+ });
899
+ // ============================================================
900
+ // SECTION 13: EDGE CASES & DEGENERATE INPUTS
901
+ // ============================================================
902
+ (0, vitest_1.describe)('Extreme: Edge Cases', () => {
903
+ (0, vitest_1.it)('single atom P — SAT', () => {
904
+ const source = `logic classical.propositional\ncheck satisfiable P`;
905
+ const out = run(source);
906
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
907
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
908
+ }, 5000);
909
+ (0, vitest_1.it)('single negation !P — SAT', () => {
910
+ const source = `logic classical.propositional\ncheck satisfiable !P`;
911
+ const out = run(source);
912
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
913
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
914
+ }, 5000);
915
+ (0, vitest_1.it)('P & !P — UNSAT', () => {
916
+ const source = `logic classical.propositional\ncheck satisfiable (P & !P)`;
917
+ const out = run(source);
918
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
919
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
920
+ }, 5000);
921
+ (0, vitest_1.it)('P | !P — SAT (tautology is satisfiable)', () => {
922
+ const source = `logic classical.propositional\ncheck satisfiable (P | !P)`;
923
+ const out = run(source);
924
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
925
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
926
+ }, 5000);
927
+ (0, vitest_1.it)('deeply nested NOT: !!!!...P (50 levels) — SAT', () => {
928
+ let formula = 'P';
929
+ for (let i = 0; i < 50; i++) {
930
+ formula = `!${formula}`;
931
+ }
932
+ const source = `logic classical.propositional\ncheck satisfiable ${formula}`;
933
+ const out = run(source);
934
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
935
+ // 50 negations = P (even number), so SAT
936
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
937
+ }, 5000);
938
+ (0, vitest_1.it)('deeply nested NOT: !!!!...P (51 levels) — SAT (it is !P, which is SAT)', () => {
939
+ let formula = 'P';
940
+ for (let i = 0; i < 51; i++) {
941
+ formula = `!${formula}`;
942
+ }
943
+ const source = `logic classical.propositional\ncheck satisfiable ${formula}`;
944
+ const out = run(source);
945
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
946
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
947
+ }, 5000);
948
+ (0, vitest_1.it)('long atom names: 100 chars each', () => {
949
+ const longName = 'A'.repeat(100);
950
+ const source = `logic classical.propositional\ncheck satisfiable (${longName} | !${longName})`;
951
+ const out = run(source);
952
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
953
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
954
+ }, 5000);
955
+ });
956
+ // ============================================================
957
+ // SECTION 14: PERFORMANCE BENCHMARKS
958
+ // ============================================================
959
+ (0, vitest_1.describe)('Extreme: Performance Bounds', () => {
960
+ (0, vitest_1.it)('200 vars random 3-SAT solves in < 10 seconds', () => {
961
+ const rng = mulberry32(2024);
962
+ const clauses = [];
963
+ for (let i = 0; i < 854; i++) {
964
+ const lits = [];
965
+ const used = new Set();
966
+ while (lits.length < 3) {
967
+ const v = Math.floor(rng() * 200) + 1;
968
+ if (used.has(v))
969
+ continue;
970
+ used.add(v);
971
+ lits.push(rng() < 0.5 ? `!P${v}` : `P${v}`);
972
+ }
973
+ clauses.push(`(${lits.join(' | ')})`);
974
+ }
975
+ const formula = clauses.join(' & ');
976
+ const start = Date.now();
977
+ const source = `
978
+ logic classical.propositional
979
+ check satisfiable ${formula}
980
+ `;
981
+ const out = run(source);
982
+ const elapsed = Date.now() - start;
983
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
984
+ (0, vitest_1.expect)(elapsed).toBeLessThan(10000);
985
+ }, 15000);
986
+ (0, vitest_1.it)('500-atom implication chain solves in < 2 seconds', () => {
987
+ const parts = [];
988
+ for (let i = 0; i < 499; i++) {
989
+ parts.push(`(I${i} -> I${i + 1})`);
990
+ }
991
+ parts.push('I0');
992
+ const formula = parts.join(' & ');
993
+ const start = Date.now();
994
+ const source = `
995
+ logic classical.propositional
996
+ check satisfiable ${formula}
997
+ `;
998
+ const out = run(source);
999
+ const elapsed = Date.now() - start;
1000
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
1001
+ (0, vitest_1.expect)(elapsed).toBeLessThan(2000);
1002
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
1003
+ }, 5000);
1004
+ });
1005
+ //# sourceMappingURL=stress-extreme.test.js.map