@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.
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/lexer/lexer.d.ts +2 -1
- package/dist/lexer/lexer.d.ts.map +1 -1
- package/dist/lexer/lexer.js +4 -2
- package/dist/lexer/lexer.js.map +1 -1
- package/dist/lexer/tokens.d.ts +17 -0
- package/dist/lexer/tokens.d.ts.map +1 -1
- package/dist/lexer/tokens.js +58 -21
- package/dist/lexer/tokens.js.map +1 -1
- package/dist/parser/parser.d.ts +2 -1
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +4 -2
- 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 +20 -0
- package/dist/profiles/classical/dpll.d.ts.map +1 -0
- package/dist/profiles/classical/dpll.js +483 -0
- package/dist/profiles/classical/dpll.js.map +1 -0
- 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 +135 -22
- 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/runtime/educational-notes.d.ts +27 -0
- package/dist/runtime/educational-notes.d.ts.map +1 -0
- package/dist/runtime/educational-notes.js +100 -0
- package/dist/runtime/educational-notes.js.map +1 -0
- 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 +9 -0
- package/dist/runtime/interpreter.d.ts.map +1 -1
- package/dist/runtime/interpreter.js +126 -6
- 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 +15 -7
- 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/stress-hardware.test.js +161 -4
- package/dist/tests/stress-hardware.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pool de notas pedagógicas contextuales para enriquecer los resultados del motor.
|
|
4
|
+
* Cada operación/resultado tiene varias notas posibles; se elige una al azar.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.pickEducationalNote = pickEducationalNote;
|
|
8
|
+
// ── Helpers ──────────────────────────────────────────────────
|
|
9
|
+
function pick(pool) {
|
|
10
|
+
return pool[Math.floor(Math.random() * pool.length)];
|
|
11
|
+
}
|
|
12
|
+
// ── Pools por operación ─────────────────────────────────────
|
|
13
|
+
const SATISFIABLE_YES = [
|
|
14
|
+
'Una fórmula satisfacible tiene al menos una valuación que la hace verdadera. No necesariamente es una tautología.',
|
|
15
|
+
'Satisfacibilidad ≠ validez. Que exista un modelo que la haga verdadera no garantiza que siempre lo sea.',
|
|
16
|
+
'El problema de satisfacibilidad (SAT) es NP-completo (Cook-Levin, 1971). Para fórmulas pequeñas se evalúa por fuerza bruta.',
|
|
17
|
+
'Una fórmula satisfacible es consistente: puede formar parte de una teoría sin contradicción.',
|
|
18
|
+
'Satisfacible significa que existe al menos una interpretación donde la fórmula es verdadera.',
|
|
19
|
+
];
|
|
20
|
+
const SATISFIABLE_NO = [
|
|
21
|
+
'Una fórmula insatisfacible (contradicción) es falsa bajo toda valuación. Su negación es una tautología.',
|
|
22
|
+
'Si φ es insatisfacible, entonces ¬φ es válida. Este es el principio de dualidad entre satisfacibilidad y validez.',
|
|
23
|
+
'Las contradicciones son útiles en lógica: si un conjunto de premisas es insatisfacible, las premisas son inconsistentes entre sí.',
|
|
24
|
+
'Toda contradicción implica cualquier cosa (ex falso quodlibet). Por eso detectar insatisfacibilidad es crucial.',
|
|
25
|
+
];
|
|
26
|
+
const VALID_YES = [
|
|
27
|
+
'Una tautología es verdadera bajo toda valuación posible. Es una verdad lógica, independiente del contenido.',
|
|
28
|
+
'Las tautologías son los teoremas de la lógica proposicional: demostrables sin premisas.',
|
|
29
|
+
'Ejemplos clásicos de tautologías: P ∨ ¬P (tercero excluido), P → P (reflexividad), ¬(P ∧ ¬P) (no contradicción).',
|
|
30
|
+
'Una fórmula válida es necesariamente verdadera en el sentido lógico: ninguna interpretación la falsifica.',
|
|
31
|
+
'Validez y satisfacibilidad son duales: φ es válida ⟺ ¬φ es insatisfacible.',
|
|
32
|
+
];
|
|
33
|
+
const VALID_NO = [
|
|
34
|
+
'Una fórmula no válida tiene al menos un contramodelo: una valuación que la hace falsa.',
|
|
35
|
+
'Que una fórmula no sea una tautología no significa que sea falsa — puede ser satisfacible (verdadera en algunos casos).',
|
|
36
|
+
'El contramodelo muestra exactamente qué asignación de verdad falsifica la fórmula.',
|
|
37
|
+
'En lógica clásica, si una fórmula no es válida, existe al menos una fila de su tabla de verdad con resultado F.',
|
|
38
|
+
];
|
|
39
|
+
const EQUIVALENT_YES = [
|
|
40
|
+
'Dos fórmulas son lógicamente equivalentes cuando tienen el mismo valor de verdad en toda valuación posible.',
|
|
41
|
+
'Equivalencia lógica: φ ≡ ψ significa que φ ↔ ψ es una tautología. Son intercambiables salva veritate.',
|
|
42
|
+
'Las equivalencias permiten simplificar fórmulas: reemplazar una sub-expresión por otra equivalente preserva el significado.',
|
|
43
|
+
'Leyes de De Morgan, doble negación, distribución — son todas equivalencias lógicas fundamentales.',
|
|
44
|
+
];
|
|
45
|
+
const EQUIVALENT_NO = [
|
|
46
|
+
'Las fórmulas no son equivalentes: existe al menos una valuación donde difieren en valor de verdad.',
|
|
47
|
+
'Que dos fórmulas no sean equivalentes no significa que sean contradictorias — pueden coincidir en muchos casos pero no en todos.',
|
|
48
|
+
'El contramodelo muestra una asignación donde una es verdadera y la otra falsa (o viceversa).',
|
|
49
|
+
];
|
|
50
|
+
const DERIVE_OK = [
|
|
51
|
+
'Derivación completada mediante reglas de inferencia. Cada paso está justificado formalmente.',
|
|
52
|
+
'En lógica proposicional clásica, si una conclusión se sigue semánticamente (⊨), también se puede derivar sintácticamente (⊢). Esto es el teorema de completitud.',
|
|
53
|
+
'La derivación formal muestra el camino paso a paso desde las premisas hasta la conclusión.',
|
|
54
|
+
'Consecuencia lógica: la conclusión no puede ser falsa si todas las premisas son verdaderas.',
|
|
55
|
+
'Las reglas de inferencia (Modus Ponens, Modus Tollens, Silogismo Hipotético, etc.) preservan la verdad de las premisas a la conclusión.',
|
|
56
|
+
];
|
|
57
|
+
const DERIVE_FAIL = [
|
|
58
|
+
'No se encontró derivación. Esto puede significar que la conclusión no se sigue de las premisas, o que se necesitan más pasos de los permitidos.',
|
|
59
|
+
'Si no hay derivación, considere agregar premisas adicionales o verificar que el argumento sea realmente válido.',
|
|
60
|
+
'Un argumento inválido tiene al menos un caso donde las premisas son verdaderas y la conclusión falsa.',
|
|
61
|
+
];
|
|
62
|
+
const PROVE_OK = [
|
|
63
|
+
'Demostrado desde la teoría: la fórmula se sigue lógicamente de los axiomas definidos.',
|
|
64
|
+
'Un teorema es una fórmula demostrable a partir de los axiomas de una teoría usando reglas de inferencia.',
|
|
65
|
+
'La demostración certifica que la fórmula es una consecuencia lógica de la teoría.',
|
|
66
|
+
];
|
|
67
|
+
const PROVE_FAIL = [
|
|
68
|
+
'No se pudo demostrar desde la teoría dada. La fórmula puede ser independiente de los axiomas.',
|
|
69
|
+
'Una fórmula no demostrable puede ser: (a) falsa en la teoría, o (b) independiente (ni demostrable ni refutable).',
|
|
70
|
+
'Considere revisar los axiomas de la teoría o agregar nuevos para cubrir este caso.',
|
|
71
|
+
];
|
|
72
|
+
const COUNTERMODEL_FOUND = [
|
|
73
|
+
'Se encontró un contramodelo: una valuación que hace la fórmula falsa. Esto demuestra que no es una tautología.',
|
|
74
|
+
'El contramodelo es la evidencia constructiva de que la fórmula puede ser falsa.',
|
|
75
|
+
'En lógica clásica, un solo contramodelo basta para refutar la validez universal de una fórmula.',
|
|
76
|
+
];
|
|
77
|
+
const COUNTERMODEL_NONE = [
|
|
78
|
+
'No existe contramodelo: la fórmula es verdadera bajo toda valuación. Es una tautología.',
|
|
79
|
+
'Si no hay contramodelo, la fórmula es válida — una verdad lógica.',
|
|
80
|
+
'La ausencia de contramodelo equivale a la validez: no hay forma de hacer la fórmula falsa.',
|
|
81
|
+
];
|
|
82
|
+
function pickEducationalNote(ctx) {
|
|
83
|
+
switch (ctx.op) {
|
|
84
|
+
case 'satisfiable':
|
|
85
|
+
return pick(ctx.sat ? SATISFIABLE_YES : SATISFIABLE_NO);
|
|
86
|
+
case 'valid':
|
|
87
|
+
return pick(ctx.valid ? VALID_YES : VALID_NO);
|
|
88
|
+
case 'equivalent':
|
|
89
|
+
return pick(ctx.equiv ? EQUIVALENT_YES : EQUIVALENT_NO);
|
|
90
|
+
case 'derive':
|
|
91
|
+
if (!ctx.ok)
|
|
92
|
+
return pick(DERIVE_FAIL);
|
|
93
|
+
return pick(DERIVE_OK);
|
|
94
|
+
case 'prove':
|
|
95
|
+
return pick(ctx.ok ? PROVE_OK : PROVE_FAIL);
|
|
96
|
+
case 'countermodel':
|
|
97
|
+
return pick(ctx.found ? COUNTERMODEL_FOUND : COUNTERMODEL_NONE);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=educational-notes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"educational-notes.js","sourceRoot":"","sources":["../../src/runtime/educational-notes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAuGH,kDAgBC;AAnHD,gEAAgE;AAEhE,SAAS,IAAI,CAAC,IAAc;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,+DAA+D;AAE/D,MAAM,eAAe,GAAa;IAChC,mHAAmH;IACnH,yGAAyG;IACzG,6HAA6H;IAC7H,8FAA8F;IAC9F,8FAA8F;CAC/F,CAAC;AAEF,MAAM,cAAc,GAAa;IAC/B,yGAAyG;IACzG,mHAAmH;IACnH,mIAAmI;IACnI,iHAAiH;CAClH,CAAC;AAEF,MAAM,SAAS,GAAa;IAC1B,6GAA6G;IAC7G,yFAAyF;IACzF,kHAAkH;IAClH,2GAA2G;IAC3G,4EAA4E;CAC7E,CAAC;AAEF,MAAM,QAAQ,GAAa;IACzB,wFAAwF;IACxF,yHAAyH;IACzH,oFAAoF;IACpF,iHAAiH;CAClH,CAAC;AAEF,MAAM,cAAc,GAAa;IAC/B,6GAA6G;IAC7G,uGAAuG;IACvG,6HAA6H;IAC7H,mGAAmG;CACpG,CAAC;AAEF,MAAM,aAAa,GAAa;IAC9B,oGAAoG;IACpG,kIAAkI;IAClI,8FAA8F;CAC/F,CAAC;AAEF,MAAM,SAAS,GAAa;IAC1B,8FAA8F;IAC9F,kKAAkK;IAClK,4FAA4F;IAC5F,6FAA6F;IAC7F,yIAAyI;CAC1I,CAAC;AAEF,MAAM,WAAW,GAAa;IAC5B,iJAAiJ;IACjJ,iHAAiH;IACjH,uGAAuG;CACxG,CAAC;AAEF,MAAM,QAAQ,GAAa;IACzB,uFAAuF;IACvF,0GAA0G;IAC1G,mFAAmF;CACpF,CAAC;AAEF,MAAM,UAAU,GAAa;IAC3B,+FAA+F;IAC/F,kHAAkH;IAClH,oFAAoF;CACrF,CAAC;AAEF,MAAM,kBAAkB,GAAa;IACnC,gHAAgH;IAChH,iFAAiF;IACjF,iGAAiG;CAClG,CAAC;AAEF,MAAM,iBAAiB,GAAa;IAClC,yFAAyF;IACzF,mEAAmE;IACnE,4FAA4F;CAC7F,CAAC;AAYF,SAAgB,mBAAmB,CAAC,GAAgB;IAClD,QAAQ,GAAG,CAAC,EAAE,EAAE,CAAC;QACf,KAAK,aAAa;YAChB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAC1D,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAChD,KAAK,YAAY;YACf,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QAC1D,KAAK,QAAQ;YACX,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC;QACzB,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAC9C,KAAK,cAAc;YACjB,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formula-factory.d.ts","sourceRoot":"","sources":["../../src/runtime/formula-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAA8B;IAElD;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO;
|
|
1
|
+
{"version":3,"file":"formula-factory.d.ts","sourceRoot":"","sources":["../../src/runtime/formula-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAA8B;IAElD;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO;IAmBlC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,IAAI;IAuBnB;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;IAIpB;;OAEG;IACH,MAAM,CAAC,IAAI,IAAI,MAAM;CAGtB"}
|
|
@@ -16,8 +16,9 @@ class FormulaFactory {
|
|
|
16
16
|
// Generar hash estructural
|
|
17
17
|
const hash = this.hash(f);
|
|
18
18
|
// Si ya existe en caché, devolver la instancia existente
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const cached = this.cache.get(hash);
|
|
20
|
+
if (cached) {
|
|
21
|
+
return cached;
|
|
21
22
|
}
|
|
22
23
|
// Si no existe, congelar la nueva instancia y guardarla
|
|
23
24
|
// Importante: No modificamos f.source para no perder info de depuración,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formula-factory.js","sourceRoot":"","sources":["../../src/runtime/formula-factory.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACH,MAAa,cAAc;IACjB,MAAM,CAAC,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IAElD;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,CAAU;QACtB,IAAI,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAEjB,2BAA2B;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE1B,yDAAyD;QACzD,
|
|
1
|
+
{"version":3,"file":"formula-factory.js","sourceRoot":"","sources":["../../src/runtime/formula-factory.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACH,MAAa,cAAc;IACjB,MAAM,CAAC,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IAElD;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,CAAU;QACtB,IAAI,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAEjB,2BAA2B;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE1B,yDAAyD;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,wDAAwD;QACxD,yEAAyE;QACzE,2EAA2E;QAC3E,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;;OAGG;IACK,MAAM,CAAC,IAAI,CAAC,CAAU;QAC5B,MAAM,KAAK,GAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,CAAC,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAExD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK;QACV,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAI;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;;AAhEH,wCAiEC"}
|
|
@@ -51,12 +51,21 @@ export declare class Interpreter {
|
|
|
51
51
|
/** Cache de resolución: fórmula original → fórmula resuelta (invalidado al cambiar bindings) */
|
|
52
52
|
private resolveCache;
|
|
53
53
|
private resolveCacheGeneration;
|
|
54
|
+
/** Memoización automática para funciones con argumentos numéricos (fibonacci, factorial, etc.) */
|
|
55
|
+
private fnMemoCache;
|
|
56
|
+
private static readonly MEMO_CACHE_MAX;
|
|
54
57
|
constructor();
|
|
55
58
|
/** Registra funciones nativas (Built-ins) para metaprogramación e interactividad */
|
|
56
59
|
private registerBuiltins;
|
|
57
60
|
private createEmptyTheory;
|
|
58
61
|
private importedFiles;
|
|
59
62
|
reset(): void;
|
|
63
|
+
/** Serializa una fórmula a una cadena para usar como clave de cache */
|
|
64
|
+
private serializeFormulaKey;
|
|
65
|
+
/** Genera la clave de memoización: nombre_función(arg1,arg2,...) */
|
|
66
|
+
private memoKey;
|
|
67
|
+
/** Verifica si una función es pura (sin side effects como print, set, check, axiom) */
|
|
68
|
+
private isPureFn;
|
|
60
69
|
private getRuntimeStepLimit;
|
|
61
70
|
private getRuntimeCallLimit;
|
|
62
71
|
private tickRuntimeStep;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../../src/runtime/interpreter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,MAAM,EAGN,eAAe,EACf,YAAY,EAGZ,cAAc,EACd,OAAO,EACR,MAAM,UAAU,CAAC;AA6ClB,OAAO,aAAa,CAAC;AAsBrB;;GAEG;AACH,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,qEAAqE;IACrE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../../src/runtime/interpreter.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,9 +15,9 @@ require("../profiles");
|
|
|
15
15
|
const compiler_1 = require("../text-layer/compiler");
|
|
16
16
|
const formula_classifier_1 = require("./formula-classifier");
|
|
17
17
|
const formula_factory_1 = require("./formula-factory");
|
|
18
|
-
const MAX_CALL_DEPTH =
|
|
19
|
-
const DEFAULT_MAX_RUNTIME_STEPS =
|
|
20
|
-
const DEFAULT_MAX_RUNTIME_CALLS =
|
|
18
|
+
const MAX_CALL_DEPTH = 50000;
|
|
19
|
+
const DEFAULT_MAX_RUNTIME_STEPS = 500000;
|
|
20
|
+
const DEFAULT_MAX_RUNTIME_CALLS = 100000;
|
|
21
21
|
class Interpreter {
|
|
22
22
|
theory;
|
|
23
23
|
profile = null;
|
|
@@ -53,6 +53,9 @@ class Interpreter {
|
|
|
53
53
|
/** Cache de resolución: fórmula original → fórmula resuelta (invalidado al cambiar bindings) */
|
|
54
54
|
resolveCache = new WeakMap();
|
|
55
55
|
resolveCacheGeneration = 0;
|
|
56
|
+
/** Memoización automática para funciones con argumentos numéricos (fibonacci, factorial, etc.) */
|
|
57
|
+
fnMemoCache = new Map();
|
|
58
|
+
static MEMO_CACHE_MAX = 50000;
|
|
56
59
|
constructor() {
|
|
57
60
|
this.theory = this.createEmptyTheory();
|
|
58
61
|
this.textLayer = (0, compiler_1.createTextLayerState)();
|
|
@@ -116,7 +119,73 @@ class Interpreter {
|
|
|
116
119
|
this.currentBindingFrame = null;
|
|
117
120
|
this.runtimeStepCount = 0;
|
|
118
121
|
this.runtimeCallCount = 0;
|
|
122
|
+
this.fnMemoCache.clear();
|
|
123
|
+
}
|
|
124
|
+
// ── Memoización de funciones ──────────────────────────────
|
|
125
|
+
/** Serializa una fórmula a una cadena para usar como clave de cache */
|
|
126
|
+
serializeFormulaKey(f) {
|
|
127
|
+
if (f.kind === 'number')
|
|
128
|
+
return `N:${f.value}`;
|
|
129
|
+
if (f.kind === 'atom')
|
|
130
|
+
return `A:${f.name}`;
|
|
131
|
+
if (f.kind === 'list')
|
|
132
|
+
return `L:[${f.args?.map((a) => this.serializeFormulaKey(a)).join(',') ?? ''}]`;
|
|
133
|
+
return `${f.kind}(${f.args?.map((a) => this.serializeFormulaKey(a)).join(',') ?? ''})`;
|
|
134
|
+
}
|
|
135
|
+
/** Genera la clave de memoización: nombre_función(arg1,arg2,...) */
|
|
136
|
+
memoKey(name, args) {
|
|
137
|
+
// Solo memoizar si todos los argumentos son valores concretos (number, atom sin variables)
|
|
138
|
+
for (const arg of args) {
|
|
139
|
+
if (arg.kind !== 'number' && arg.kind !== 'atom')
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return `${name}(${args.map((a) => this.serializeFormulaKey(a)).join(',')})`;
|
|
143
|
+
}
|
|
144
|
+
/** Verifica si una función es pura (sin side effects como print, set, check, axiom) */
|
|
145
|
+
isPureFn(fn) {
|
|
146
|
+
const check = (stmts) => {
|
|
147
|
+
for (const s of stmts) {
|
|
148
|
+
switch (s.kind) {
|
|
149
|
+
case 'print_cmd':
|
|
150
|
+
case 'set_cmd':
|
|
151
|
+
case 'derive_cmd':
|
|
152
|
+
case 'check_valid_cmd':
|
|
153
|
+
case 'check_satisfiable_cmd':
|
|
154
|
+
case 'check_equivalent_cmd':
|
|
155
|
+
case 'prove_cmd':
|
|
156
|
+
case 'axiom_decl':
|
|
157
|
+
case 'theorem_decl':
|
|
158
|
+
case 'theory_decl':
|
|
159
|
+
case 'import_decl':
|
|
160
|
+
case 'export_decl':
|
|
161
|
+
case 'logic_decl':
|
|
162
|
+
return false;
|
|
163
|
+
case 'if_stmt': {
|
|
164
|
+
const ifS = s;
|
|
165
|
+
for (const branch of ifS.branches) {
|
|
166
|
+
if (!check(branch.body))
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
if (ifS.elseBranch && !check(ifS.elseBranch))
|
|
170
|
+
return false;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case 'for_stmt':
|
|
174
|
+
if (!check(s.body))
|
|
175
|
+
return false;
|
|
176
|
+
break;
|
|
177
|
+
case 'while_stmt':
|
|
178
|
+
if (!check(s.body))
|
|
179
|
+
return false;
|
|
180
|
+
break;
|
|
181
|
+
// let_decl, return_stmt, fn_call, fn_decl are considered pure
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
};
|
|
186
|
+
return check(fn.body);
|
|
119
187
|
}
|
|
188
|
+
// ── Fin memoización ───────────────────────────────────────
|
|
120
189
|
getRuntimeStepLimit() {
|
|
121
190
|
const configured = this.getBinding('max_steps') || this.getBinding('max_runtime_steps');
|
|
122
191
|
if (configured?.kind === 'number' && configured.value && configured.value > 0) {
|
|
@@ -230,7 +299,16 @@ class Interpreter {
|
|
|
230
299
|
this.stdoutLines = [];
|
|
231
300
|
this.runtimeStepCount = 0;
|
|
232
301
|
this.runtimeCallCount = 0;
|
|
233
|
-
|
|
302
|
+
// Pre-scan for profile declarations to enable profile-aware lexing.
|
|
303
|
+
// Only restrict keywords when there's exactly one profile in the source.
|
|
304
|
+
// Multi-profile files use all keywords for safety.
|
|
305
|
+
const profileMatches = source.match(/(?:^|\n)\s*(?:logic|logica)\s+([\w.]+)/g);
|
|
306
|
+
let detectedProfile;
|
|
307
|
+
if (profileMatches && profileMatches.length === 1) {
|
|
308
|
+
const m = profileMatches[0].match(/(?:logic|logica)\s+([\w.]+)/);
|
|
309
|
+
detectedProfile = m ? m[1] : undefined;
|
|
310
|
+
}
|
|
311
|
+
const parser = new parser_1.Parser(file, detectedProfile);
|
|
234
312
|
const program = parser.parse(source);
|
|
235
313
|
this.diagnostics.push(...parser.diagnostics);
|
|
236
314
|
if (parser.diagnostics.some((d) => d.severity === 'error')) {
|
|
@@ -1264,9 +1342,24 @@ class Interpreter {
|
|
|
1264
1342
|
this.returnSignal = true;
|
|
1265
1343
|
}
|
|
1266
1344
|
executeFnCall(stmt) {
|
|
1267
|
-
|
|
1268
|
-
|
|
1345
|
+
// ── Memoización: verificar cache antes de ejecutar ──
|
|
1346
|
+
const evaluatedArgs = stmt.args.map((a) => this.evaluateFormulaValue(a));
|
|
1347
|
+
const memoStmt = { name: stmt.name, args: evaluatedArgs };
|
|
1348
|
+
const fn = this.functions.get(stmt.name);
|
|
1349
|
+
let mKey = null;
|
|
1350
|
+
if (fn && this.isPureFn(fn)) {
|
|
1351
|
+
mKey = this.memoKey(stmt.name, evaluatedArgs);
|
|
1352
|
+
if (mKey !== null && this.fnMemoCache.has(mKey)) {
|
|
1353
|
+
return this.fnMemoCache.get(mKey);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
const initial = this.startFunctionFrame(memoStmt, undefined);
|
|
1357
|
+
if ('result' in initial) {
|
|
1358
|
+
if (mKey !== null && this.fnMemoCache.size < Interpreter.MEMO_CACHE_MAX) {
|
|
1359
|
+
this.fnMemoCache.set(mKey, initial.result);
|
|
1360
|
+
}
|
|
1269
1361
|
return initial.result;
|
|
1362
|
+
}
|
|
1270
1363
|
const callStack = [initial.frame];
|
|
1271
1364
|
let finalResult = undefined;
|
|
1272
1365
|
while (callStack.length > 0) {
|
|
@@ -1315,9 +1408,25 @@ class Interpreter {
|
|
|
1315
1408
|
}
|
|
1316
1409
|
this.dispatchRuntimeStatement(nextStmt, frame.runtimeStack);
|
|
1317
1410
|
}
|
|
1411
|
+
// ── Memoización: guardar resultado ──
|
|
1412
|
+
if (mKey !== null && this.fnMemoCache.size < Interpreter.MEMO_CACHE_MAX) {
|
|
1413
|
+
this.fnMemoCache.set(mKey, finalResult);
|
|
1414
|
+
}
|
|
1318
1415
|
return finalResult;
|
|
1319
1416
|
}
|
|
1320
1417
|
startFunctionFrame(stmt, continuation, inheritedReturnState) {
|
|
1418
|
+
// ── Memoización: comprobar cache antes de crear frame ──
|
|
1419
|
+
const fnDef = this.functions.get(stmt.name);
|
|
1420
|
+
if (fnDef && this.isPureFn(fnDef)) {
|
|
1421
|
+
const evaluatedArgs = stmt.args.map((a) => this.evaluateFormulaValue(a));
|
|
1422
|
+
const mk = this.memoKey(stmt.name, evaluatedArgs);
|
|
1423
|
+
if (mk !== null && this.fnMemoCache.has(mk)) {
|
|
1424
|
+
return {
|
|
1425
|
+
result: this.fnMemoCache.get(mk),
|
|
1426
|
+
resultContinuation: continuation || { type: 'discard' },
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1321
1430
|
this.callDepth++;
|
|
1322
1431
|
if (this.callDepth > MAX_CALL_DEPTH) {
|
|
1323
1432
|
this.callDepth--;
|
|
@@ -1410,6 +1519,12 @@ class Interpreter {
|
|
|
1410
1519
|
const savedReturnValue = inheritedReturnState?.value ?? this.returnValue;
|
|
1411
1520
|
this.returnSignal = false;
|
|
1412
1521
|
this.returnValue = undefined;
|
|
1522
|
+
// Calcular clave de memoización para este frame
|
|
1523
|
+
const evaluatedArgValues = Array.from(this.currentBindingFrame.bindings.values());
|
|
1524
|
+
let frameMemoKey = null;
|
|
1525
|
+
if (this.isPureFn(fn)) {
|
|
1526
|
+
frameMemoKey = this.memoKey(name, evaluatedArgValues);
|
|
1527
|
+
}
|
|
1413
1528
|
return {
|
|
1414
1529
|
name,
|
|
1415
1530
|
runtimeStack: [{ kind: 'statements', statements: fn.body, index: 0 }],
|
|
@@ -1418,12 +1533,17 @@ class Interpreter {
|
|
|
1418
1533
|
savedReturnValue,
|
|
1419
1534
|
scopeSnapshot,
|
|
1420
1535
|
continuation,
|
|
1536
|
+
memoKey: frameMemoKey,
|
|
1421
1537
|
};
|
|
1422
1538
|
}
|
|
1423
1539
|
finishFunctionFrame(frame) {
|
|
1424
1540
|
const result = this.returnValue;
|
|
1425
1541
|
this.returnSignal = frame.savedReturnSignal;
|
|
1426
1542
|
this.returnValue = frame.savedReturnValue;
|
|
1543
|
+
// ── Memoización: guardar resultado al finalizar frame ──
|
|
1544
|
+
if (frame.memoKey && this.fnMemoCache.size < Interpreter.MEMO_CACHE_MAX) {
|
|
1545
|
+
this.fnMemoCache.set(frame.memoKey, result);
|
|
1546
|
+
}
|
|
1427
1547
|
this.discardFunctionFrameState(frame);
|
|
1428
1548
|
this.callDepth--;
|
|
1429
1549
|
return result;
|