@stevenvo780/st-lang 2.7.0 → 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 (80) 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/lexer/lexer.d.ts +2 -1
  6. package/dist/lexer/lexer.d.ts.map +1 -1
  7. package/dist/lexer/lexer.js +4 -2
  8. package/dist/lexer/lexer.js.map +1 -1
  9. package/dist/lexer/tokens.d.ts +17 -0
  10. package/dist/lexer/tokens.d.ts.map +1 -1
  11. package/dist/lexer/tokens.js +58 -21
  12. package/dist/lexer/tokens.js.map +1 -1
  13. package/dist/parser/parser.d.ts +2 -1
  14. package/dist/parser/parser.d.ts.map +1 -1
  15. package/dist/parser/parser.js +4 -2
  16. package/dist/parser/parser.js.map +1 -1
  17. package/dist/profiles/classical/cdcl.d.ts +34 -0
  18. package/dist/profiles/classical/cdcl.d.ts.map +1 -0
  19. package/dist/profiles/classical/cdcl.js +843 -0
  20. package/dist/profiles/classical/cdcl.js.map +1 -0
  21. package/dist/profiles/classical/dpll.d.ts +20 -0
  22. package/dist/profiles/classical/dpll.d.ts.map +1 -0
  23. package/dist/profiles/classical/dpll.js +483 -0
  24. package/dist/profiles/classical/dpll.js.map +1 -0
  25. package/dist/profiles/classical/first-order.d.ts.map +1 -1
  26. package/dist/profiles/classical/first-order.js +20 -10
  27. package/dist/profiles/classical/first-order.js.map +1 -1
  28. package/dist/profiles/classical/parallel-sat.d.ts +62 -0
  29. package/dist/profiles/classical/parallel-sat.d.ts.map +1 -0
  30. package/dist/profiles/classical/parallel-sat.js +630 -0
  31. package/dist/profiles/classical/parallel-sat.js.map +1 -0
  32. package/dist/profiles/classical/propositional.d.ts.map +1 -1
  33. package/dist/profiles/classical/propositional.js +135 -22
  34. package/dist/profiles/classical/propositional.js.map +1 -1
  35. package/dist/profiles/classical/sat-preprocess.d.ts +17 -0
  36. package/dist/profiles/classical/sat-preprocess.d.ts.map +1 -0
  37. package/dist/profiles/classical/sat-preprocess.js +372 -0
  38. package/dist/profiles/classical/sat-preprocess.js.map +1 -0
  39. package/dist/profiles/classical/undecidability-detector.d.ts +13 -0
  40. package/dist/profiles/classical/undecidability-detector.d.ts.map +1 -0
  41. package/dist/profiles/classical/undecidability-detector.js +277 -0
  42. package/dist/profiles/classical/undecidability-detector.js.map +1 -0
  43. package/dist/profiles/paraconsistent/belnap.d.ts.map +1 -1
  44. package/dist/profiles/paraconsistent/belnap.js +4 -2
  45. package/dist/profiles/paraconsistent/belnap.js.map +1 -1
  46. package/dist/profiles/shared/tableau-engine.d.ts.map +1 -1
  47. package/dist/profiles/shared/tableau-engine.js +3 -1
  48. package/dist/profiles/shared/tableau-engine.js.map +1 -1
  49. package/dist/runtime/educational-notes.d.ts +27 -0
  50. package/dist/runtime/educational-notes.d.ts.map +1 -0
  51. package/dist/runtime/educational-notes.js +100 -0
  52. package/dist/runtime/educational-notes.js.map +1 -0
  53. package/dist/runtime/formula-factory.d.ts.map +1 -1
  54. package/dist/runtime/formula-factory.js +3 -2
  55. package/dist/runtime/formula-factory.js.map +1 -1
  56. package/dist/runtime/interpreter.d.ts +9 -0
  57. package/dist/runtime/interpreter.d.ts.map +1 -1
  58. package/dist/runtime/interpreter.js +126 -6
  59. package/dist/runtime/interpreter.js.map +1 -1
  60. package/dist/tests/benchmark-cdcl.test.d.ts +2 -0
  61. package/dist/tests/benchmark-cdcl.test.d.ts.map +1 -0
  62. package/dist/tests/benchmark-cdcl.test.js +172 -0
  63. package/dist/tests/benchmark-cdcl.test.js.map +1 -0
  64. package/dist/tests/limits.test.js +15 -7
  65. package/dist/tests/limits.test.js.map +1 -1
  66. package/dist/tests/parallel-sat.test.d.ts +2 -0
  67. package/dist/tests/parallel-sat.test.d.ts.map +1 -0
  68. package/dist/tests/parallel-sat.test.js +351 -0
  69. package/dist/tests/parallel-sat.test.js.map +1 -0
  70. package/dist/tests/stress-cdcl.test.d.ts +2 -0
  71. package/dist/tests/stress-cdcl.test.d.ts.map +1 -0
  72. package/dist/tests/stress-cdcl.test.js +792 -0
  73. package/dist/tests/stress-cdcl.test.js.map +1 -0
  74. package/dist/tests/stress-extreme.test.d.ts +2 -0
  75. package/dist/tests/stress-extreme.test.d.ts.map +1 -0
  76. package/dist/tests/stress-extreme.test.js +1005 -0
  77. package/dist/tests/stress-extreme.test.js.map +1 -0
  78. package/dist/tests/stress-hardware.test.js +161 -4
  79. package/dist/tests/stress-hardware.test.js.map +1 -1
  80. package/package.json +1 -1
@@ -0,0 +1,792 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * ST CDCL SAT Solver — Extreme Stress Tests
5
+ * ===========================================
6
+ * Tests para el nuevo solver CDCL con:
7
+ * - Fórmulas de 100-500+ átomos
8
+ * - Random 3-SAT en el punto de transición de fase (ratio 4.27)
9
+ * - Pigeonhole Principle (n+1, n) para n grande
10
+ * - Cadenas de implicación extremas
11
+ * - Fórmulas con simetría (XOR chains)
12
+ * - Preprocessing effectiveness
13
+ * - Recursividad controlada vs imposible
14
+ * - Timeout y graceful degradation
15
+ * - Pattern detection accuracy
16
+ */
17
+ const vitest_1 = require("vitest");
18
+ const interpreter_1 = require("../runtime/interpreter");
19
+ const formula_factory_1 = require("../runtime/formula-factory");
20
+ const cdcl_1 = require("../profiles/classical/cdcl");
21
+ const dpll_1 = require("../profiles/classical/dpll");
22
+ (0, vitest_1.afterEach)(() => {
23
+ formula_factory_1.FormulaFactory.clear();
24
+ });
25
+ function run(source) {
26
+ const interp = new interpreter_1.Interpreter();
27
+ return interp.execute(source, '<cdcl-stress>');
28
+ }
29
+ /** Strip diacritics for accent-insensitive comparison */
30
+ function stripAccents(s) {
31
+ return s.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
32
+ }
33
+ // ============================================================
34
+ // 1. LARGE SATISFIABLE FORMULAS
35
+ // ============================================================
36
+ (0, vitest_1.describe)('CDCL Stress: Large Satisfiable Formulas', () => {
37
+ (0, vitest_1.it)('100 atoms — conjunction (trivially SAT)', () => {
38
+ const atoms = Array.from({ length: 100 }, (_, i) => `A${i}`);
39
+ const formula = atoms.join(' & ');
40
+ const source = `
41
+ logic classical.propositional
42
+ check satisfiable ${formula}
43
+ `;
44
+ const out = run(source);
45
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
46
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
47
+ }, 15000);
48
+ (0, vitest_1.it)('100 atoms — disjunction (trivially SAT)', () => {
49
+ const atoms = Array.from({ length: 100 }, (_, i) => `B${i}`);
50
+ const formula = atoms.join(' | ');
51
+ const source = `
52
+ logic classical.propositional
53
+ check satisfiable ${formula}
54
+ `;
55
+ const out = run(source);
56
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
57
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
58
+ }, 15000);
59
+ (0, vitest_1.it)('200 atoms — implication chain (SAT)', () => {
60
+ // P0 -> P1 -> P2 -> ... -> P199 is satisfiable (set P0=false or all true)
61
+ const atoms = Array.from({ length: 200 }, (_, i) => `P${i}`);
62
+ const implications = [];
63
+ for (let i = 0; i < atoms.length - 1; i++) {
64
+ implications.push(`(${atoms[i]} -> ${atoms[i + 1]})`);
65
+ }
66
+ const formula = implications.join(' & ');
67
+ const source = `
68
+ logic classical.propositional
69
+ check satisfiable ${formula}
70
+ `;
71
+ const out = run(source);
72
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
73
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
74
+ }, 30000);
75
+ (0, vitest_1.it)('100 atoms — biconditional chain (SAT: all same value)', () => {
76
+ const atoms = Array.from({ length: 100 }, (_, i) => `E${i}`);
77
+ const bicons = [];
78
+ for (let i = 0; i < atoms.length - 1; i++) {
79
+ bicons.push(`(${atoms[i]} <-> ${atoms[i + 1]})`);
80
+ }
81
+ const formula = bicons.join(' & ');
82
+ const source = `
83
+ logic classical.propositional
84
+ check satisfiable ${formula}
85
+ `;
86
+ const out = run(source);
87
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
88
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
89
+ }, 30000);
90
+ (0, vitest_1.it)('50 atoms — complex nested formula (SAT)', () => {
91
+ // (A0 | A1) & (A2 | A3) & ... with implications
92
+ const clauses = [];
93
+ for (let i = 0; i < 50; i += 2) {
94
+ clauses.push(`(X${i} | X${i + 1})`);
95
+ }
96
+ for (let i = 0; i < 48; i++) {
97
+ clauses.push(`(X${i} -> X${i + 2})`);
98
+ }
99
+ const formula = clauses.join(' & ');
100
+ const source = `
101
+ logic classical.propositional
102
+ check satisfiable ${formula}
103
+ `;
104
+ const out = run(source);
105
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
106
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
107
+ }, 30000);
108
+ });
109
+ // ============================================================
110
+ // 2. LARGE UNSATISFIABLE FORMULAS
111
+ // ============================================================
112
+ (0, vitest_1.describe)('CDCL Stress: Large Unsatisfiable Formulas', () => {
113
+ (0, vitest_1.it)('100 atoms — direct contradiction (A & !A)', () => {
114
+ const atoms = Array.from({ length: 100 }, (_, i) => `C${i}`);
115
+ const formula = atoms.join(' & ') + ' & !C50';
116
+ // C0 & C1 & ... & C99 & !C50 → UNSAT
117
+ const source = `
118
+ logic classical.propositional
119
+ check satisfiable ${formula}
120
+ `;
121
+ const out = run(source);
122
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
123
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
124
+ }, 15000);
125
+ (0, vitest_1.it)('50 atoms — circular implications leading to contradiction', () => {
126
+ // P0 -> P1 -> ... -> P49 -> !P0 & P0
127
+ const atoms = Array.from({ length: 50 }, (_, i) => `R${i}`);
128
+ const implications = [];
129
+ for (let i = 0; i < atoms.length - 1; i++) {
130
+ implications.push(`(${atoms[i]} -> ${atoms[i + 1]})`);
131
+ }
132
+ implications.push(`(${atoms[atoms.length - 1]} -> !${atoms[0]})`);
133
+ implications.push(atoms[0]); // Force P0 = true
134
+ const formula = implications.join(' & ');
135
+ const source = `
136
+ logic classical.propositional
137
+ check satisfiable ${formula}
138
+ `;
139
+ const out = run(source);
140
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
141
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
142
+ }, 30000);
143
+ (0, vitest_1.it)('30 atoms — every pair mutually exclusive + all must be true', () => {
144
+ const n = 30;
145
+ const atoms = Array.from({ length: n }, (_, i) => `M${i}`);
146
+ const clauses = [];
147
+ // All must be true
148
+ for (const a of atoms) {
149
+ clauses.push(a);
150
+ }
151
+ // At most one can be true (pairwise exclusion)
152
+ for (let i = 0; i < n; i++) {
153
+ for (let j = i + 1; j < n; j++) {
154
+ clauses.push(`!(${atoms[i]} & ${atoms[j]})`);
155
+ }
156
+ }
157
+ const formula = clauses.join(' & ');
158
+ const source = `
159
+ logic classical.propositional
160
+ check satisfiable ${formula}
161
+ `;
162
+ const out = run(source);
163
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
164
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
165
+ }, 30000);
166
+ });
167
+ // ============================================================
168
+ // 3. PIGEONHOLE PRINCIPLE
169
+ // ============================================================
170
+ (0, vitest_1.describe)('CDCL Stress: Pigeonhole Principle', () => {
171
+ function generatePigeonhole(pigeons, holes) {
172
+ const clauses = [];
173
+ // At-least-one: each pigeon goes to at least one hole
174
+ for (let i = 0; i < pigeons; i++) {
175
+ const holeOptions = Array.from({ length: holes }, (_, j) => `P${i}H${j}`);
176
+ clauses.push(`(${holeOptions.join(' | ')})`);
177
+ }
178
+ // At-most-one: no two pigeons in the same hole
179
+ for (let j = 0; j < holes; j++) {
180
+ for (let i = 0; i < pigeons; i++) {
181
+ for (let k = i + 1; k < pigeons; k++) {
182
+ clauses.push(`!(P${i}H${j} & P${k}H${j})`);
183
+ }
184
+ }
185
+ }
186
+ return clauses.join(' & ');
187
+ }
188
+ (0, vitest_1.it)('pigeonhole(3,2) — 6 vars, UNSAT', () => {
189
+ const formula = generatePigeonhole(3, 2);
190
+ const source = `
191
+ logic classical.propositional
192
+ check satisfiable ${formula}
193
+ `;
194
+ const out = run(source);
195
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
196
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
197
+ }, 10000);
198
+ (0, vitest_1.it)('pigeonhole(4,3) — 12 vars, UNSAT', () => {
199
+ const formula = generatePigeonhole(4, 3);
200
+ const source = `
201
+ logic classical.propositional
202
+ check satisfiable ${formula}
203
+ `;
204
+ const out = run(source);
205
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
206
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
207
+ }, 15000);
208
+ (0, vitest_1.it)('pigeonhole(5,4) — 20 vars, UNSAT', () => {
209
+ const formula = generatePigeonhole(5, 4);
210
+ const source = `
211
+ logic classical.propositional
212
+ check satisfiable ${formula}
213
+ `;
214
+ const out = run(source);
215
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
216
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
217
+ }, 30000);
218
+ (0, vitest_1.it)('pigeonhole(6,5) — 30 vars, UNSAT (hard for DPLL)', () => {
219
+ const formula = generatePigeonhole(6, 5);
220
+ const source = `
221
+ logic classical.propositional
222
+ check satisfiable ${formula}
223
+ `;
224
+ const out = run(source);
225
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
226
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
227
+ }, 60000);
228
+ (0, vitest_1.it)('pigeonhole(3,3) — 9 vars, SAT (enough holes)', () => {
229
+ const formula = generatePigeonhole(3, 3);
230
+ const source = `
231
+ logic classical.propositional
232
+ check satisfiable ${formula}
233
+ `;
234
+ const out = run(source);
235
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
236
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
237
+ }, 15000);
238
+ (0, vitest_1.it)('pigeonhole(4,4) — 16 vars, SAT (enough holes)', () => {
239
+ const formula = generatePigeonhole(4, 4);
240
+ const source = `
241
+ logic classical.propositional
242
+ check satisfiable ${formula}
243
+ `;
244
+ const out = run(source);
245
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
246
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
247
+ }, 15000);
248
+ });
249
+ // ============================================================
250
+ // 4. RANDOM 3-SAT AT PHASE TRANSITION
251
+ // ============================================================
252
+ (0, vitest_1.describe)('CDCL Stress: Random 3-SAT', () => {
253
+ function generateRandom3SAT(numVars, numClauses, seed) {
254
+ // Simple seeded PRNG
255
+ let s = seed;
256
+ function rand() {
257
+ s = (s * 1103515245 + 12345) & 0x7fffffff;
258
+ return s;
259
+ }
260
+ const clauses = [];
261
+ for (let c = 0; c < numClauses; c++) {
262
+ const vars = new Set();
263
+ while (vars.size < 3) {
264
+ vars.add((rand() % numVars) + 1);
265
+ }
266
+ const lits = Array.from(vars).map((v) => {
267
+ const name = `V${v}`;
268
+ return rand() % 2 === 0 ? name : `!${name}`;
269
+ });
270
+ clauses.push(`(${lits.join(' | ')})`);
271
+ }
272
+ return clauses.join(' & ');
273
+ }
274
+ (0, vitest_1.it)('50 vars, 200 clauses (ratio 4.0 — likely SAT region)', () => {
275
+ const formula = generateRandom3SAT(50, 200, 42);
276
+ const source = `
277
+ logic classical.propositional
278
+ check satisfiable ${formula}
279
+ `;
280
+ const out = run(source);
281
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
282
+ // May be SAT or UNSAT — just shouldn't crash or timeout
283
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
284
+ }, 30000);
285
+ (0, vitest_1.it)('50 vars, 213 clauses (ratio 4.26 — phase transition)', () => {
286
+ const formula = generateRandom3SAT(50, 213, 1337);
287
+ const source = `
288
+ logic classical.propositional
289
+ check satisfiable ${formula}
290
+ `;
291
+ const out = run(source);
292
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
293
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
294
+ }, 30000);
295
+ (0, vitest_1.it)('100 vars, 427 clauses (ratio 4.27 — hard region)', () => {
296
+ const formula = generateRandom3SAT(100, 427, 2024);
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).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
304
+ }, 60000);
305
+ (0, vitest_1.it)('75 vars, 350 clauses — deterministic result consistency', () => {
306
+ // Run same formula twice, should get same result
307
+ const formula = generateRandom3SAT(75, 350, 99999);
308
+ const source = `
309
+ logic classical.propositional
310
+ check satisfiable ${formula}
311
+ `;
312
+ const out1 = run(source);
313
+ const out2 = run(source);
314
+ (0, vitest_1.expect)(out1.exitCode).toBe(0);
315
+ (0, vitest_1.expect)(out2.exitCode).toBe(0);
316
+ // Results should be identical
317
+ const result1 = out1.stdout.includes('INSATISFACIBLE') ? 'UNSAT' : 'SAT';
318
+ const result2 = out2.stdout.includes('INSATISFACIBLE') ? 'UNSAT' : 'SAT';
319
+ (0, vitest_1.expect)(result1).toBe(result2);
320
+ }, 30000);
321
+ });
322
+ // ============================================================
323
+ // 5. TAUTOLOGY AND VALIDITY WITH CDCL
324
+ // ============================================================
325
+ (0, vitest_1.describe)('CDCL Stress: Tautology/Validity with Many Atoms', () => {
326
+ (0, vitest_1.it)('100 atoms — tautology (each atom OR its negation)', () => {
327
+ const atoms = Array.from({ length: 100 }, (_, i) => `T${i}`);
328
+ const tautology = atoms.map((a) => `(${a} | !${a})`).join(' & ');
329
+ const source = `
330
+ logic classical.propositional
331
+ check valid ${tautology}
332
+ `;
333
+ const out = run(source);
334
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
335
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
336
+ }, 30000);
337
+ (0, vitest_1.it)('50 atoms — non-tautology (conjunction), countermodel exists', () => {
338
+ const atoms = Array.from({ length: 50 }, (_, i) => `N${i}`);
339
+ const formula = atoms.join(' & ');
340
+ const source = `
341
+ logic classical.propositional
342
+ countermodel ${formula}
343
+ `;
344
+ const out = run(source);
345
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
346
+ (0, vitest_1.expect)(out.stdout).toContain('Contramodelo');
347
+ }, 30000);
348
+ (0, vitest_1.it)('200 atoms — De Morgan tautology', () => {
349
+ // !(A0 & A1) <-> (!A0 | !A1) for many pairs
350
+ const parts = [];
351
+ for (let i = 0; i < 200; i += 2) {
352
+ parts.push(`(!(A${i} & A${i + 1}) <-> (!A${i} | !A${i + 1}))`);
353
+ }
354
+ const formula = parts.join(' & ');
355
+ const source = `
356
+ logic classical.propositional
357
+ check valid ${formula}
358
+ `;
359
+ const out = run(source);
360
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
361
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
362
+ }, 30000);
363
+ (0, vitest_1.it)('100 atoms — distributivity tautology', () => {
364
+ // (A & (B | C)) <-> ((A & B) | (A & C)) for 33 triples
365
+ const parts = [];
366
+ for (let i = 0; i < 99; i += 3) {
367
+ parts.push(`((X${i} & (X${i + 1} | X${i + 2})) <-> ((X${i} & X${i + 1}) | (X${i} & X${i + 2})))`);
368
+ }
369
+ const formula = parts.join(' & ');
370
+ const source = `
371
+ logic classical.propositional
372
+ check valid ${formula}
373
+ `;
374
+ const out = run(source);
375
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
376
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
377
+ }, 30000);
378
+ });
379
+ // ============================================================
380
+ // 6. CDCL API DIRECT TESTS
381
+ // ============================================================
382
+ (0, vitest_1.describe)('CDCL Direct API Tests', () => {
383
+ (0, vitest_1.it)('cdcl() returns stats with conflict/propagation counts', () => {
384
+ // A somewhat hard formula to force some conflicts
385
+ const formula = {
386
+ kind: 'and',
387
+ args: [
388
+ {
389
+ kind: 'or',
390
+ args: [
391
+ { kind: 'atom', name: 'A' },
392
+ { kind: 'atom', name: 'B' },
393
+ ],
394
+ },
395
+ {
396
+ kind: 'or',
397
+ args: [
398
+ { kind: 'atom', name: 'A' },
399
+ { kind: 'not', args: [{ kind: 'atom', name: 'B' }] },
400
+ ],
401
+ },
402
+ {
403
+ kind: 'or',
404
+ args: [
405
+ { kind: 'not', args: [{ kind: 'atom', name: 'A' }] },
406
+ { kind: 'atom', name: 'B' },
407
+ ],
408
+ },
409
+ {
410
+ kind: 'or',
411
+ args: [
412
+ { kind: 'not', args: [{ kind: 'atom', name: 'A' }] },
413
+ { kind: 'not', args: [{ kind: 'atom', name: 'B' }] },
414
+ ],
415
+ },
416
+ ],
417
+ };
418
+ const result = (0, cdcl_1.cdcl)(formula);
419
+ (0, vitest_1.expect)(result.satisfiable).toBe(false);
420
+ (0, vitest_1.expect)(result.stats).toBeDefined();
421
+ (0, vitest_1.expect)(result.stats?.solveTimeMs).toBeGreaterThanOrEqual(0);
422
+ });
423
+ (0, vitest_1.it)('cdcl() returns satisfying model for SAT formula', () => {
424
+ const formula = {
425
+ kind: 'and',
426
+ args: [
427
+ {
428
+ kind: 'or',
429
+ args: [
430
+ { kind: 'atom', name: 'X' },
431
+ { kind: 'atom', name: 'Y' },
432
+ ],
433
+ },
434
+ {
435
+ kind: 'or',
436
+ args: [
437
+ { kind: 'not', args: [{ kind: 'atom', name: 'X' }] },
438
+ { kind: 'atom', name: 'Y' },
439
+ ],
440
+ },
441
+ ],
442
+ };
443
+ const result = (0, cdcl_1.cdcl)(formula);
444
+ (0, vitest_1.expect)(result.satisfiable).toBe(true);
445
+ (0, vitest_1.expect)(result.model).toBeDefined();
446
+ // Y must be true in any model
447
+ (0, vitest_1.expect)(result.model?.['Y']).toBe(true);
448
+ });
449
+ (0, vitest_1.it)('dpll() backward compatibility — uses CDCL internally', () => {
450
+ const formula = {
451
+ kind: 'or',
452
+ args: [
453
+ { kind: 'atom', name: 'P' },
454
+ { kind: 'atom', name: 'Q' },
455
+ ],
456
+ };
457
+ const result = (0, dpll_1.dpll)(formula);
458
+ (0, vitest_1.expect)(result.satisfiable).toBe(true);
459
+ (0, vitest_1.expect)(result.model).toBeDefined();
460
+ });
461
+ });
462
+ // ============================================================
463
+ // 7. XOR CHAINS — HARD FOR NAIVE SOLVERS
464
+ // ============================================================
465
+ (0, vitest_1.describe)('CDCL Stress: XOR Chains', () => {
466
+ (0, vitest_1.it)('20 vars — XOR chain (SAT with specific assignment)', () => {
467
+ // X0 XOR X1, X1 XOR X2, ..., X18 XOR X19, X0 — forces alternating
468
+ const parts = [];
469
+ for (let i = 0; i < 19; i++) {
470
+ parts.push(`(X${i} xor X${i + 1})`);
471
+ }
472
+ parts.push('X0');
473
+ const formula = parts.join(' & ');
474
+ const source = `
475
+ logic classical.propositional
476
+ check satisfiable ${formula}
477
+ `;
478
+ const out = run(source);
479
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
480
+ // Should be SAT: X0=T, X1=F, X2=T, X3=F, ...
481
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
482
+ }, 15000);
483
+ (0, vitest_1.it)('21 vars — XOR chain with even constraint (UNSAT)', () => {
484
+ // X0 XOR X1, X1 XOR X2, ..., X19 XOR X20, X0, X20
485
+ // Forces alternating but X0=T, X20=T requires even length between them (20),
486
+ // which means X20 should be T... Let's construct a proper UNSAT:
487
+ // XOR chain of 20: X0 xor X1, ..., X18 xor X19, X0, !X19 with odd length
488
+ const parts = [];
489
+ for (let i = 0; i < 20; i++) {
490
+ parts.push(`(X${i} xor X${i + 1})`);
491
+ }
492
+ // X0 = true, X20 = true → needs even length (20 is even) → SAT
493
+ // Force UNSAT: X0 = true AND X20 = true AND odd chain = 21 items
494
+ parts.push('X0');
495
+ parts.push('!X20'); // X0=T → X1=F → X2=T → ... → X20=T, but we want X20=F
496
+ const formula = parts.join(' & ');
497
+ const source = `
498
+ logic classical.propositional
499
+ check satisfiable ${formula}
500
+ `;
501
+ const out = run(source);
502
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
503
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
504
+ }, 15000);
505
+ });
506
+ // ============================================================
507
+ // 8. CONTROLLED RECURSION — WHAT SHOULD WORK
508
+ // ============================================================
509
+ (0, vitest_1.describe)('CDCL Stress: Controlled Recursion in ST', () => {
510
+ (0, vitest_1.it)('deeply nested implications (100 levels) — SAT', () => {
511
+ // ((((P -> Q) -> R) -> S) -> T) ... depth 100
512
+ let formula = 'Z0';
513
+ for (let i = 1; i < 100; i++) {
514
+ formula = `(${formula} -> Z${i})`;
515
+ }
516
+ const source = `
517
+ logic classical.propositional
518
+ check satisfiable ${formula}
519
+ `;
520
+ const out = run(source);
521
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
522
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
523
+ }, 30000);
524
+ (0, vitest_1.it)('deeply nested biconditionals (50 levels) — SAT', () => {
525
+ let formula = 'B0';
526
+ for (let i = 1; i < 50; i++) {
527
+ formula = `(${formula} <-> B${i})`;
528
+ }
529
+ const source = `
530
+ logic classical.propositional
531
+ check satisfiable ${formula}
532
+ `;
533
+ const out = run(source);
534
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
535
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
536
+ }, 30000);
537
+ (0, vitest_1.it)('arithmetic recursion: factorial with depth limit', () => {
538
+ const source = `
539
+ logic arithmetic
540
+ fn fact(N) {
541
+ if valid N <= 1 {
542
+ return 1
543
+ }
544
+ let prev = N - 1
545
+ let res = fact(prev)
546
+ return N * res
547
+ }
548
+ let r = fact(10)
549
+ print r
550
+ `;
551
+ const out = run(source);
552
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
553
+ (0, vitest_1.expect)(out.stdout).toContain('3628800');
554
+ }, 10000);
555
+ (0, vitest_1.it)('arithmetic recursion: fibonacci with memoization pattern', () => {
556
+ const source = `
557
+ logic arithmetic
558
+ fn fib(N) {
559
+ if valid N <= 0 { return 0 }
560
+ if valid N <= 1 { return 1 }
561
+ let a = N - 1
562
+ let b = N - 2
563
+ let ra = fib(a)
564
+ let rb = fib(b)
565
+ return ra + rb
566
+ }
567
+ let r = fib(15)
568
+ print r
569
+ `;
570
+ const out = run(source);
571
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
572
+ (0, vitest_1.expect)(out.stdout).toContain('610');
573
+ }, 30000);
574
+ (0, vitest_1.it)('controlled iteration: sum with nested loops', () => {
575
+ // ST uses { } list syntax for for-loops, not ranges
576
+ // 10x10 = 100 iterations to test accumulation
577
+ const source = `
578
+ logic arithmetic
579
+ let x = 0
580
+ for i in {1,2,3,4,5,6,7,8,9,10} {
581
+ for j in {1,2,3,4,5,6,7,8,9,10} {
582
+ set x = x + 1
583
+ }
584
+ }
585
+ print x
586
+ `;
587
+ const out = run(source);
588
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
589
+ (0, vitest_1.expect)(out.stdout).toContain('100');
590
+ }, 15000);
591
+ });
592
+ // ============================================================
593
+ // 9. DENIED RECURSION — WHAT SHOULD BE CAUGHT
594
+ // ============================================================
595
+ (0, vitest_1.describe)('CDCL Stress: Impossible Recursion Detection', () => {
596
+ (0, vitest_1.it)('infinite recursion is caught gracefully', () => {
597
+ const source = `
598
+ logic arithmetic
599
+ fn loop(n) {
600
+ return loop(n + 1)
601
+ }
602
+ let r = loop(0)
603
+ explain r
604
+ `;
605
+ const out = run(source);
606
+ // Should either exit with error or handle gracefully
607
+ // Not crash with stack overflow
608
+ (0, vitest_1.expect)(out.exitCode !== undefined).toBe(true);
609
+ }, 15000);
610
+ (0, vitest_1.it)('mutual infinite recursion caught', () => {
611
+ const source = `
612
+ logic arithmetic
613
+ fn ping(n) {
614
+ return pong(n + 1)
615
+ }
616
+ fn pong(n) {
617
+ return ping(n + 1)
618
+ }
619
+ let r = ping(0)
620
+ explain r
621
+ `;
622
+ const out = run(source);
623
+ (0, vitest_1.expect)(out.exitCode !== undefined).toBe(true);
624
+ }, 15000);
625
+ });
626
+ // ============================================================
627
+ // 10. PREPROCESSING EFFECTIVENESS
628
+ // ============================================================
629
+ (0, vitest_1.describe)('CDCL Stress: Preprocessing', () => {
630
+ (0, vitest_1.it)('redundant clauses eliminated by subsumption', () => {
631
+ // (A | B) & (A | B | C) — second is subsumed
632
+ // Add many such pairs
633
+ const parts = [];
634
+ for (let i = 0; i < 50; i++) {
635
+ parts.push(`(X${i} | Y${i})`);
636
+ parts.push(`(X${i} | Y${i} | Z${i})`); // subsumed by the first
637
+ }
638
+ parts.push('X0'); // force at least one value
639
+ const formula = parts.join(' & ');
640
+ const source = `
641
+ logic classical.propositional
642
+ check satisfiable ${formula}
643
+ `;
644
+ const out = run(source);
645
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
646
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
647
+ }, 15000);
648
+ (0, vitest_1.it)('unit propagation cascade from preprocessing', () => {
649
+ // A & (A -> B) & (B -> C) & (C -> D) & ... all resolved by preprocessing
650
+ const atoms = Array.from({ length: 100 }, (_, i) => `U${i}`);
651
+ const parts = ['U0'];
652
+ for (let i = 0; i < atoms.length - 1; i++) {
653
+ parts.push(`(${atoms[i]} -> ${atoms[i + 1]})`);
654
+ }
655
+ const formula = parts.join(' & ');
656
+ const source = `
657
+ logic classical.propositional
658
+ check satisfiable ${formula}
659
+ `;
660
+ const out = run(source);
661
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
662
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
663
+ }, 15000);
664
+ });
665
+ // ============================================================
666
+ // 11. EDGE CASES
667
+ // ============================================================
668
+ (0, vitest_1.describe)('CDCL Stress: Edge Cases', () => {
669
+ (0, vitest_1.it)('single atom — trivially SAT', () => {
670
+ const source = `
671
+ logic classical.propositional
672
+ check satisfiable P
673
+ `;
674
+ const out = run(source);
675
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
676
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
677
+ }, 5000);
678
+ (0, vitest_1.it)('negation of single atom — SAT', () => {
679
+ const source = `
680
+ logic classical.propositional
681
+ check satisfiable !P
682
+ `;
683
+ const out = run(source);
684
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
685
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
686
+ }, 5000);
687
+ (0, vitest_1.it)('P & !P — trivially UNSAT', () => {
688
+ const source = `
689
+ logic classical.propositional
690
+ check satisfiable (P & !P)
691
+ `;
692
+ const out = run(source);
693
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
694
+ (0, vitest_1.expect)(out.stdout).toContain('INSATISFACIBLE');
695
+ }, 5000);
696
+ (0, vitest_1.it)('empty disjunction equivalents handled', () => {
697
+ const source = `
698
+ logic classical.propositional
699
+ check valid (P | !P)
700
+ `;
701
+ const out = run(source);
702
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
703
+ (0, vitest_1.expect)(stripAccents(out.stdout).toUpperCase()).toContain('VALIDA');
704
+ }, 5000);
705
+ (0, vitest_1.it)('50 identical clauses — deduplication', () => {
706
+ const repeated = Array.from({ length: 50 }, () => '(A | B | C)').join(' & ');
707
+ const source = `
708
+ logic classical.propositional
709
+ check satisfiable ${repeated}
710
+ `;
711
+ const out = run(source);
712
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
713
+ (0, vitest_1.expect)(out.stdout).toContain('SATISFACIBLE');
714
+ }, 10000);
715
+ });
716
+ // ============================================================
717
+ // 12. THEORY + DERIVATION WITH LARGE ATOM COUNTS
718
+ // ============================================================
719
+ (0, vitest_1.describe)('CDCL Stress: Theory Derivations with CDCL', () => {
720
+ (0, vitest_1.it)('theory with 30 axioms deriving complex conclusion via DPLL/CDCL', () => {
721
+ const axioms = [];
722
+ const names = [];
723
+ for (let i = 0; i < 29; i++) {
724
+ axioms.push(`axiom a${i} = A${i} -> A${i + 1}`);
725
+ names.push(`a${i}`);
726
+ }
727
+ names.push('base');
728
+ const source = `
729
+ logic classical.propositional
730
+ ${axioms.join('\n ')}
731
+ axiom base = A0
732
+ derive A29 from {${names.join(', ')}}
733
+ `;
734
+ const out = run(source);
735
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
736
+ (0, vitest_1.expect)(out.stdout).toContain('[derive]');
737
+ }, 30000);
738
+ });
739
+ // ============================================================
740
+ // 13. MIXED CONNECTIVE STRESS
741
+ // ============================================================
742
+ (0, vitest_1.describe)('CDCL Stress: Mixed Connectives', () => {
743
+ (0, vitest_1.it)('NAND chain — 50 atoms', () => {
744
+ const parts = [];
745
+ for (let i = 0; i < 49; i++) {
746
+ parts.push(`(N${i} nand N${i + 1})`);
747
+ }
748
+ const formula = parts.join(' & ');
749
+ const source = `
750
+ logic classical.propositional
751
+ check satisfiable ${formula}
752
+ `;
753
+ const out = run(source);
754
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
755
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
756
+ }, 30000);
757
+ (0, vitest_1.it)('NOR chain — 50 atoms', () => {
758
+ const parts = [];
759
+ for (let i = 0; i < 49; i++) {
760
+ parts.push(`(N${i} nor N${i + 1})`);
761
+ }
762
+ const formula = parts.join(' & ');
763
+ const source = `
764
+ logic classical.propositional
765
+ check satisfiable ${formula}
766
+ `;
767
+ const out = run(source);
768
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
769
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
770
+ }, 30000);
771
+ (0, vitest_1.it)('complex mixed: AND + OR + XOR + IMPLIES + BICONDITIONAL (30 atoms)', () => {
772
+ const parts = [];
773
+ for (let i = 0; i < 30; i += 5) {
774
+ parts.push(`(A${i} & A${i + 1})`);
775
+ parts.push(`(A${i + 1} | A${i + 2})`);
776
+ parts.push(`(A${i + 2} xor A${i + 3})`);
777
+ parts.push(`(A${i + 3} -> A${i + 4})`);
778
+ if (i + 5 < 30) {
779
+ parts.push(`(A${i + 4} <-> A${i + 5})`);
780
+ }
781
+ }
782
+ const formula = parts.join(' & ');
783
+ const source = `
784
+ logic classical.propositional
785
+ check satisfiable ${formula}
786
+ `;
787
+ const out = run(source);
788
+ (0, vitest_1.expect)(out.exitCode).toBe(0);
789
+ (0, vitest_1.expect)(out.stdout).toMatch(/SATISFACIBLE|INSATISFACIBLE/);
790
+ }, 30000);
791
+ });
792
+ //# sourceMappingURL=stress-cdcl.test.js.map