@stevenvo780/st-lang 2.7.1 → 3.0.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.
- package/dist/ast/nodes.d.ts +35 -2
- package/dist/ast/nodes.d.ts.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/lexer/lexer.d.ts.map +1 -1
- package/dist/lexer/lexer.js +4 -0
- package/dist/lexer/lexer.js.map +1 -1
- package/dist/lexer/tokens.d.ts +8 -0
- package/dist/lexer/tokens.d.ts.map +1 -1
- package/dist/lexer/tokens.js +23 -0
- package/dist/lexer/tokens.js.map +1 -1
- package/dist/parser/parser.d.ts +6 -0
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +171 -6
- package/dist/parser/parser.js.map +1 -1
- package/dist/profiles/classical/cdcl.d.ts +34 -0
- package/dist/profiles/classical/cdcl.d.ts.map +1 -0
- package/dist/profiles/classical/cdcl.js +843 -0
- package/dist/profiles/classical/cdcl.js.map +1 -0
- package/dist/profiles/classical/dpll.d.ts +11 -1
- package/dist/profiles/classical/dpll.d.ts.map +1 -1
- package/dist/profiles/classical/dpll.js +54 -17
- package/dist/profiles/classical/dpll.js.map +1 -1
- package/dist/profiles/classical/first-order.d.ts.map +1 -1
- package/dist/profiles/classical/first-order.js +20 -10
- package/dist/profiles/classical/first-order.js.map +1 -1
- package/dist/profiles/classical/parallel-sat.d.ts +62 -0
- package/dist/profiles/classical/parallel-sat.d.ts.map +1 -0
- package/dist/profiles/classical/parallel-sat.js +630 -0
- package/dist/profiles/classical/parallel-sat.js.map +1 -0
- package/dist/profiles/classical/propositional.d.ts.map +1 -1
- package/dist/profiles/classical/propositional.js +35 -19
- package/dist/profiles/classical/propositional.js.map +1 -1
- package/dist/profiles/classical/sat-preprocess.d.ts +17 -0
- package/dist/profiles/classical/sat-preprocess.d.ts.map +1 -0
- package/dist/profiles/classical/sat-preprocess.js +372 -0
- package/dist/profiles/classical/sat-preprocess.js.map +1 -0
- package/dist/profiles/classical/undecidability-detector.d.ts +13 -0
- package/dist/profiles/classical/undecidability-detector.d.ts.map +1 -0
- package/dist/profiles/classical/undecidability-detector.js +277 -0
- package/dist/profiles/classical/undecidability-detector.js.map +1 -0
- package/dist/profiles/paraconsistent/belnap.d.ts.map +1 -1
- package/dist/profiles/paraconsistent/belnap.js +4 -2
- package/dist/profiles/paraconsistent/belnap.js.map +1 -1
- package/dist/profiles/shared/tableau-engine.d.ts.map +1 -1
- package/dist/profiles/shared/tableau-engine.js +3 -1
- package/dist/profiles/shared/tableau-engine.js.map +1 -1
- package/dist/protocol/handler.d.ts.map +1 -1
- package/dist/protocol/handler.js +327 -88
- package/dist/protocol/handler.js.map +1 -1
- package/dist/runtime/formula-factory.d.ts.map +1 -1
- package/dist/runtime/formula-factory.js +3 -2
- package/dist/runtime/formula-factory.js.map +1 -1
- package/dist/runtime/interpreter.d.ts +33 -0
- package/dist/runtime/interpreter.d.ts.map +1 -1
- package/dist/runtime/interpreter.js +516 -5
- package/dist/runtime/interpreter.js.map +1 -1
- package/dist/tests/benchmark-cdcl.test.d.ts +2 -0
- package/dist/tests/benchmark-cdcl.test.d.ts.map +1 -0
- package/dist/tests/benchmark-cdcl.test.js +172 -0
- package/dist/tests/benchmark-cdcl.test.js.map +1 -0
- package/dist/tests/limits.test.js +11 -4
- package/dist/tests/limits.test.js.map +1 -1
- package/dist/tests/parallel-sat.test.d.ts +2 -0
- package/dist/tests/parallel-sat.test.d.ts.map +1 -0
- package/dist/tests/parallel-sat.test.js +351 -0
- package/dist/tests/parallel-sat.test.js.map +1 -0
- package/dist/tests/stress-cdcl.test.d.ts +2 -0
- package/dist/tests/stress-cdcl.test.d.ts.map +1 -0
- package/dist/tests/stress-cdcl.test.js +792 -0
- package/dist/tests/stress-cdcl.test.js.map +1 -0
- package/dist/tests/stress-extreme.test.d.ts +2 -0
- package/dist/tests/stress-extreme.test.d.ts.map +1 -0
- package/dist/tests/stress-extreme.test.js +1005 -0
- package/dist/tests/stress-extreme.test.js.map +1 -0
- package/dist/tests/v3-features.test.d.ts +2 -0
- package/dist/tests/v3-features.test.d.ts.map +1 -0
- package/dist/tests/v3-features.test.js +529 -0
- package/dist/tests/v3-features.test.js.map +1 -0
- package/dist/tests/v3-stress.test.d.ts +2 -0
- package/dist/tests/v3-stress.test.d.ts.map +1 -0
- package/dist/tests/v3-stress.test.js +755 -0
- package/dist/tests/v3-stress.test.js.map +1 -0
- package/dist/text-layer/compiler.d.ts +4 -1
- package/dist/text-layer/compiler.d.ts.map +1 -1
- package/dist/text-layer/compiler.js +35 -0
- package/dist/text-layer/compiler.js.map +1 -1
- package/dist/types/index.d.ts +27 -1
- package/dist/types/index.d.ts.map +1 -1
- 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
|