@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,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;IAkBlC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,IAAI;IAuBnB;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;IAIpB;;OAEG;IACH,MAAM,CAAC,IAAI,IAAI,MAAM;CAGtB"}
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
- if (this.cache.has(hash)) {
20
- return this.cache.get(hash);
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,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;QAC/B,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;;AA/DH,wCAgEC"}
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":"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"}
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 = 10000;
19
- const DEFAULT_MAX_RUNTIME_STEPS = 100000;
20
- const DEFAULT_MAX_RUNTIME_CALLS = 7000;
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
- const parser = new parser_1.Parser(file);
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
- const initial = this.startFunctionFrame(stmt, undefined);
1268
- if ('result' in initial)
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;