@stevenvo780/st-lang 3.2.3 → 4.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.
Files changed (445) hide show
  1. package/README.md +47 -7
  2. package/dist/api.d.ts +2 -0
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +5 -1
  5. package/dist/api.js.map +1 -1
  6. package/dist/argumentation/dot.d.ts +3 -0
  7. package/dist/argumentation/dot.d.ts.map +1 -0
  8. package/dist/argumentation/dot.js +25 -0
  9. package/dist/argumentation/dot.js.map +1 -0
  10. package/dist/argumentation/extensions.d.ts +11 -0
  11. package/dist/argumentation/extensions.d.ts.map +1 -0
  12. package/dist/argumentation/extensions.js +173 -0
  13. package/dist/argumentation/extensions.js.map +1 -0
  14. package/dist/argumentation/framework.d.ts +13 -0
  15. package/dist/argumentation/framework.d.ts.map +1 -0
  16. package/dist/argumentation/framework.js +117 -0
  17. package/dist/argumentation/framework.js.map +1 -0
  18. package/dist/argumentation/index.d.ts +6 -0
  19. package/dist/argumentation/index.d.ts.map +1 -0
  20. package/dist/argumentation/index.js +33 -0
  21. package/dist/argumentation/index.js.map +1 -0
  22. package/dist/argumentation/types.d.ts +11 -0
  23. package/dist/argumentation/types.d.ts.map +1 -0
  24. package/dist/argumentation/types.js +8 -0
  25. package/dist/argumentation/types.js.map +1 -0
  26. package/dist/ast/visitor.d.ts +95 -0
  27. package/dist/ast/visitor.d.ts.map +1 -0
  28. package/dist/ast/visitor.js +223 -0
  29. package/dist/ast/visitor.js.map +1 -0
  30. package/dist/citation-reasoning/derive.d.ts +31 -0
  31. package/dist/citation-reasoning/derive.d.ts.map +1 -0
  32. package/dist/citation-reasoning/derive.js +157 -0
  33. package/dist/citation-reasoning/derive.js.map +1 -0
  34. package/dist/citation-reasoning/index.d.ts +4 -0
  35. package/dist/citation-reasoning/index.d.ts.map +1 -0
  36. package/dist/citation-reasoning/index.js +10 -0
  37. package/dist/citation-reasoning/index.js.map +1 -0
  38. package/dist/citation-reasoning/types.d.ts +36 -0
  39. package/dist/citation-reasoning/types.d.ts.map +1 -0
  40. package/dist/citation-reasoning/types.js +6 -0
  41. package/dist/citation-reasoning/types.js.map +1 -0
  42. package/dist/educational/checker.d.ts +3 -0
  43. package/dist/educational/checker.d.ts.map +1 -0
  44. package/dist/educational/checker.js +244 -0
  45. package/dist/educational/checker.js.map +1 -0
  46. package/dist/educational/generator.d.ts +4 -0
  47. package/dist/educational/generator.d.ts.map +1 -0
  48. package/dist/educational/generator.js +158 -0
  49. package/dist/educational/generator.js.map +1 -0
  50. package/dist/educational/index.d.ts +6 -0
  51. package/dist/educational/index.d.ts.map +1 -0
  52. package/dist/educational/index.js +21 -0
  53. package/dist/educational/index.js.map +1 -0
  54. package/dist/educational/normalize.d.ts +6 -0
  55. package/dist/educational/normalize.d.ts.map +1 -0
  56. package/dist/educational/normalize.js +124 -0
  57. package/dist/educational/normalize.js.map +1 -0
  58. package/dist/educational/rng.d.ts +10 -0
  59. package/dist/educational/rng.d.ts.map +1 -0
  60. package/dist/educational/rng.js +47 -0
  61. package/dist/educational/rng.js.map +1 -0
  62. package/dist/educational/templates.d.ts +30 -0
  63. package/dist/educational/templates.d.ts.map +1 -0
  64. package/dist/educational/templates.js +567 -0
  65. package/dist/educational/templates.js.map +1 -0
  66. package/dist/educational/types.d.ts +44 -0
  67. package/dist/educational/types.d.ts.map +1 -0
  68. package/dist/educational/types.js +20 -0
  69. package/dist/educational/types.js.map +1 -0
  70. package/dist/exporters/coq/index.d.ts +35 -0
  71. package/dist/exporters/coq/index.d.ts.map +1 -0
  72. package/dist/exporters/coq/index.js +299 -0
  73. package/dist/exporters/coq/index.js.map +1 -0
  74. package/dist/fol-prover/cnf.d.ts +10 -0
  75. package/dist/fol-prover/cnf.d.ts.map +1 -0
  76. package/dist/fol-prover/cnf.js +357 -0
  77. package/dist/fol-prover/cnf.js.map +1 -0
  78. package/dist/fol-prover/index.d.ts +7 -0
  79. package/dist/fol-prover/index.d.ts.map +1 -0
  80. package/dist/fol-prover/index.js +27 -0
  81. package/dist/fol-prover/index.js.map +1 -0
  82. package/dist/fol-prover/prove.d.ts +4 -0
  83. package/dist/fol-prover/prove.d.ts.map +1 -0
  84. package/dist/fol-prover/prove.js +34 -0
  85. package/dist/fol-prover/prove.js.map +1 -0
  86. package/dist/fol-prover/resolve.d.ts +27 -0
  87. package/dist/fol-prover/resolve.d.ts.map +1 -0
  88. package/dist/fol-prover/resolve.js +234 -0
  89. package/dist/fol-prover/resolve.js.map +1 -0
  90. package/dist/fol-prover/types.d.ts +34 -0
  91. package/dist/fol-prover/types.d.ts.map +1 -0
  92. package/dist/fol-prover/types.js +38 -0
  93. package/dist/fol-prover/types.js.map +1 -0
  94. package/dist/fol-prover/unify.d.ts +9 -0
  95. package/dist/fol-prover/unify.d.ts.map +1 -0
  96. package/dist/fol-prover/unify.js +110 -0
  97. package/dist/fol-prover/unify.js.map +1 -0
  98. package/dist/hyperreal/index.d.ts +45 -0
  99. package/dist/hyperreal/index.d.ts.map +1 -0
  100. package/dist/hyperreal/index.js +183 -0
  101. package/dist/hyperreal/index.js.map +1 -0
  102. package/dist/index.d.ts +26 -0
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +72 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/lsp/index.d.ts +6 -0
  107. package/dist/lsp/index.d.ts.map +1 -0
  108. package/dist/lsp/index.js +29 -0
  109. package/dist/lsp/index.js.map +1 -0
  110. package/dist/lsp/protocol.d.ts +20 -0
  111. package/dist/lsp/protocol.d.ts.map +1 -0
  112. package/dist/lsp/protocol.js +64 -0
  113. package/dist/lsp/protocol.js.map +1 -0
  114. package/dist/lsp/server.d.ts +47 -0
  115. package/dist/lsp/server.d.ts.map +1 -0
  116. package/dist/lsp/server.js +529 -0
  117. package/dist/lsp/server.js.map +1 -0
  118. package/dist/lsp/types.d.ts +152 -0
  119. package/dist/lsp/types.d.ts.map +1 -0
  120. package/dist/lsp/types.js +70 -0
  121. package/dist/lsp/types.js.map +1 -0
  122. package/dist/parser/formulas.d.ts +7 -0
  123. package/dist/parser/formulas.d.ts.map +1 -0
  124. package/dist/parser/formulas.js +511 -0
  125. package/dist/parser/formulas.js.map +1 -0
  126. package/dist/parser/parser.d.ts +11 -41
  127. package/dist/parser/parser.d.ts.map +1 -1
  128. package/dist/parser/parser.js +410 -1037
  129. package/dist/parser/parser.js.map +1 -1
  130. package/dist/parser/state.d.ts +34 -0
  131. package/dist/parser/state.d.ts.map +1 -0
  132. package/dist/parser/state.js +163 -0
  133. package/dist/parser/state.js.map +1 -0
  134. package/dist/plugin-system/demo-min-logic.d.ts +3 -0
  135. package/dist/plugin-system/demo-min-logic.d.ts.map +1 -0
  136. package/dist/plugin-system/demo-min-logic.js +116 -0
  137. package/dist/plugin-system/demo-min-logic.js.map +1 -0
  138. package/dist/plugin-system/errors.d.ts +9 -0
  139. package/dist/plugin-system/errors.d.ts.map +1 -0
  140. package/dist/plugin-system/errors.js +24 -0
  141. package/dist/plugin-system/errors.js.map +1 -0
  142. package/dist/plugin-system/index.d.ts +6 -0
  143. package/dist/plugin-system/index.d.ts.map +1 -0
  144. package/dist/plugin-system/index.js +14 -0
  145. package/dist/plugin-system/index.js.map +1 -0
  146. package/dist/plugin-system/registry.d.ts +12 -0
  147. package/dist/plugin-system/registry.d.ts.map +1 -0
  148. package/dist/plugin-system/registry.js +46 -0
  149. package/dist/plugin-system/registry.js.map +1 -0
  150. package/dist/plugin-system/types.d.ts +23 -0
  151. package/dist/plugin-system/types.d.ts.map +1 -0
  152. package/dist/plugin-system/types.js +3 -0
  153. package/dist/plugin-system/types.js.map +1 -0
  154. package/dist/plugin-system/validate.d.ts +4 -0
  155. package/dist/plugin-system/validate.d.ts.map +1 -0
  156. package/dist/plugin-system/validate.js +60 -0
  157. package/dist/plugin-system/validate.js.map +1 -0
  158. package/dist/profiles/classical/parallel-sat.js +3 -3
  159. package/dist/profiles/classical/parallel-sat.js.map +1 -1
  160. package/dist/proof-exchange/index.d.ts +26 -0
  161. package/dist/proof-exchange/index.d.ts.map +1 -0
  162. package/dist/proof-exchange/index.js +94 -0
  163. package/dist/proof-exchange/index.js.map +1 -0
  164. package/dist/runtime/memo/cache.d.ts +32 -0
  165. package/dist/runtime/memo/cache.d.ts.map +1 -0
  166. package/dist/runtime/memo/cache.js +129 -0
  167. package/dist/runtime/memo/cache.js.map +1 -0
  168. package/dist/runtime/memo/hash.d.ts +9 -0
  169. package/dist/runtime/memo/hash.d.ts.map +1 -0
  170. package/dist/runtime/memo/hash.js +87 -0
  171. package/dist/runtime/memo/hash.js.map +1 -0
  172. package/dist/runtime/memo/index.d.ts +4 -0
  173. package/dist/runtime/memo/index.d.ts.map +1 -0
  174. package/dist/runtime/memo/index.js +8 -0
  175. package/dist/runtime/memo/index.js.map +1 -0
  176. package/dist/runtime/parallel/index.d.ts +34 -0
  177. package/dist/runtime/parallel/index.d.ts.map +1 -0
  178. package/dist/runtime/parallel/index.js +220 -0
  179. package/dist/runtime/parallel/index.js.map +1 -0
  180. package/dist/runtime/parallel/worker.d.ts +22 -0
  181. package/dist/runtime/parallel/worker.d.ts.map +1 -0
  182. package/dist/runtime/parallel/worker.js +43 -0
  183. package/dist/runtime/parallel/worker.js.map +1 -0
  184. package/dist/runtime/smt/index.d.ts +6 -0
  185. package/dist/runtime/smt/index.d.ts.map +1 -0
  186. package/dist/runtime/smt/index.js +18 -0
  187. package/dist/runtime/smt/index.js.map +1 -0
  188. package/dist/runtime/smt/mock-backend.d.ts +30 -0
  189. package/dist/runtime/smt/mock-backend.d.ts.map +1 -0
  190. package/dist/runtime/smt/mock-backend.js +460 -0
  191. package/dist/runtime/smt/mock-backend.js.map +1 -0
  192. package/dist/runtime/smt/serializer.d.ts +21 -0
  193. package/dist/runtime/smt/serializer.d.ts.map +1 -0
  194. package/dist/runtime/smt/serializer.js +314 -0
  195. package/dist/runtime/smt/serializer.js.map +1 -0
  196. package/dist/runtime/smt/subprocess-backend.d.ts +62 -0
  197. package/dist/runtime/smt/subprocess-backend.d.ts.map +1 -0
  198. package/dist/runtime/smt/subprocess-backend.js +261 -0
  199. package/dist/runtime/smt/subprocess-backend.js.map +1 -0
  200. package/dist/runtime/smt/types.d.ts +57 -0
  201. package/dist/runtime/smt/types.d.ts.map +1 -0
  202. package/dist/runtime/smt/types.js +6 -0
  203. package/dist/runtime/smt/types.js.map +1 -0
  204. package/dist/runtime/streaming/index.d.ts +4 -0
  205. package/dist/runtime/streaming/index.d.ts.map +1 -0
  206. package/dist/runtime/streaming/index.js +9 -0
  207. package/dist/runtime/streaming/index.js.map +1 -0
  208. package/dist/runtime/streaming/stream-eval.d.ts +31 -0
  209. package/dist/runtime/streaming/stream-eval.d.ts.map +1 -0
  210. package/dist/runtime/streaming/stream-eval.js +155 -0
  211. package/dist/runtime/streaming/stream-eval.js.map +1 -0
  212. package/dist/runtime/streaming/types.d.ts +33 -0
  213. package/dist/runtime/streaming/types.d.ts.map +1 -0
  214. package/dist/runtime/streaming/types.js +6 -0
  215. package/dist/runtime/streaming/types.js.map +1 -0
  216. package/dist/runtime/typecheck/checker.d.ts +72 -0
  217. package/dist/runtime/typecheck/checker.d.ts.map +1 -0
  218. package/dist/runtime/typecheck/checker.js +462 -0
  219. package/dist/runtime/typecheck/checker.js.map +1 -0
  220. package/dist/runtime/typecheck/index.d.ts +4 -0
  221. package/dist/runtime/typecheck/index.d.ts.map +1 -0
  222. package/dist/runtime/typecheck/index.js +13 -0
  223. package/dist/runtime/typecheck/index.js.map +1 -0
  224. package/dist/runtime/typecheck/levenshtein.d.ts +11 -0
  225. package/dist/runtime/typecheck/levenshtein.d.ts.map +1 -0
  226. package/dist/runtime/typecheck/levenshtein.js +49 -0
  227. package/dist/runtime/typecheck/levenshtein.js.map +1 -0
  228. package/dist/runtime/typecheck/types.d.ts +14 -0
  229. package/dist/runtime/typecheck/types.d.ts.map +1 -0
  230. package/dist/runtime/typecheck/types.js +26 -0
  231. package/dist/runtime/typecheck/types.js.map +1 -0
  232. package/dist/solver/cdcl-v2/clause-learning.d.ts +33 -0
  233. package/dist/solver/cdcl-v2/clause-learning.d.ts.map +1 -0
  234. package/dist/solver/cdcl-v2/clause-learning.js +110 -0
  235. package/dist/solver/cdcl-v2/clause-learning.js.map +1 -0
  236. package/dist/solver/cdcl-v2/index.d.ts +9 -0
  237. package/dist/solver/cdcl-v2/index.d.ts.map +1 -0
  238. package/dist/solver/cdcl-v2/index.js +39 -0
  239. package/dist/solver/cdcl-v2/index.js.map +1 -0
  240. package/dist/solver/cdcl-v2/lbd.d.ts +34 -0
  241. package/dist/solver/cdcl-v2/lbd.d.ts.map +1 -0
  242. package/dist/solver/cdcl-v2/lbd.js +72 -0
  243. package/dist/solver/cdcl-v2/lbd.js.map +1 -0
  244. package/dist/solver/cdcl-v2/luby.d.ts +28 -0
  245. package/dist/solver/cdcl-v2/luby.d.ts.map +1 -0
  246. package/dist/solver/cdcl-v2/luby.js +70 -0
  247. package/dist/solver/cdcl-v2/luby.js.map +1 -0
  248. package/dist/solver/cdcl-v2/phase-saving.d.ts +14 -0
  249. package/dist/solver/cdcl-v2/phase-saving.d.ts.map +1 -0
  250. package/dist/solver/cdcl-v2/phase-saving.js +44 -0
  251. package/dist/solver/cdcl-v2/phase-saving.js.map +1 -0
  252. package/dist/solver/cdcl-v2/solver.d.ts +10 -0
  253. package/dist/solver/cdcl-v2/solver.d.ts.map +1 -0
  254. package/dist/solver/cdcl-v2/solver.js +442 -0
  255. package/dist/solver/cdcl-v2/solver.js.map +1 -0
  256. package/dist/solver/cdcl-v2/state.d.ts +54 -0
  257. package/dist/solver/cdcl-v2/state.d.ts.map +1 -0
  258. package/dist/solver/cdcl-v2/state.js +22 -0
  259. package/dist/solver/cdcl-v2/state.js.map +1 -0
  260. package/dist/solver/cdcl-v2/vsids.d.ts +19 -0
  261. package/dist/solver/cdcl-v2/vsids.d.ts.map +1 -0
  262. package/dist/solver/cdcl-v2/vsids.js +77 -0
  263. package/dist/solver/cdcl-v2/vsids.js.map +1 -0
  264. package/dist/tests/agora-integration-fixtures.test.js.map +1 -1
  265. package/dist/tests/argumentation/dung.test.d.ts +2 -0
  266. package/dist/tests/argumentation/dung.test.d.ts.map +1 -0
  267. package/dist/tests/argumentation/dung.test.js +219 -0
  268. package/dist/tests/argumentation/dung.test.js.map +1 -0
  269. package/dist/tests/citation-reasoning/citation-reasoning.test.d.ts +2 -0
  270. package/dist/tests/citation-reasoning/citation-reasoning.test.d.ts.map +1 -0
  271. package/dist/tests/citation-reasoning/citation-reasoning.test.js +240 -0
  272. package/dist/tests/citation-reasoning/citation-reasoning.test.js.map +1 -0
  273. package/dist/tests/coverage-fill-api.test.d.ts +7 -0
  274. package/dist/tests/coverage-fill-api.test.d.ts.map +1 -0
  275. package/dist/tests/coverage-fill-api.test.js +310 -0
  276. package/dist/tests/coverage-fill-api.test.js.map +1 -0
  277. package/dist/tests/coverage-fill-aristotelian.test.d.ts +7 -0
  278. package/dist/tests/coverage-fill-aristotelian.test.d.ts.map +1 -0
  279. package/dist/tests/coverage-fill-aristotelian.test.js +377 -0
  280. package/dist/tests/coverage-fill-aristotelian.test.js.map +1 -0
  281. package/dist/tests/coverage-fill-belnap.test.d.ts +6 -0
  282. package/dist/tests/coverage-fill-belnap.test.d.ts.map +1 -0
  283. package/dist/tests/coverage-fill-belnap.test.js +277 -0
  284. package/dist/tests/coverage-fill-belnap.test.js.map +1 -0
  285. package/dist/tests/coverage-fill-cross-system.test.d.ts +6 -0
  286. package/dist/tests/coverage-fill-cross-system.test.d.ts.map +1 -0
  287. package/dist/tests/coverage-fill-cross-system.test.js +75 -0
  288. package/dist/tests/coverage-fill-cross-system.test.js.map +1 -0
  289. package/dist/tests/coverage-fill-fallacies.test.d.ts +6 -0
  290. package/dist/tests/coverage-fill-fallacies.test.d.ts.map +1 -0
  291. package/dist/tests/coverage-fill-fallacies.test.js +287 -0
  292. package/dist/tests/coverage-fill-fallacies.test.js.map +1 -0
  293. package/dist/tests/coverage-fill-format.test.d.ts +7 -0
  294. package/dist/tests/coverage-fill-format.test.d.ts.map +1 -0
  295. package/dist/tests/coverage-fill-format.test.js +455 -0
  296. package/dist/tests/coverage-fill-format.test.js.map +1 -0
  297. package/dist/tests/coverage-fill-intuitionistic.test.d.ts +6 -0
  298. package/dist/tests/coverage-fill-intuitionistic.test.d.ts.map +1 -0
  299. package/dist/tests/coverage-fill-intuitionistic.test.js +293 -0
  300. package/dist/tests/coverage-fill-intuitionistic.test.js.map +1 -0
  301. package/dist/tests/coverage-fill-probabilistic.test.d.ts +7 -0
  302. package/dist/tests/coverage-fill-probabilistic.test.d.ts.map +1 -0
  303. package/dist/tests/coverage-fill-probabilistic.test.js +314 -0
  304. package/dist/tests/coverage-fill-probabilistic.test.js.map +1 -0
  305. package/dist/tests/educational/checker.test.d.ts +2 -0
  306. package/dist/tests/educational/checker.test.d.ts.map +1 -0
  307. package/dist/tests/educational/checker.test.js +212 -0
  308. package/dist/tests/educational/checker.test.js.map +1 -0
  309. package/dist/tests/educational/generator.test.d.ts +2 -0
  310. package/dist/tests/educational/generator.test.d.ts.map +1 -0
  311. package/dist/tests/educational/generator.test.js +137 -0
  312. package/dist/tests/educational/generator.test.js.map +1 -0
  313. package/dist/tests/exporters/coq/coq-exporter.test.d.ts +2 -0
  314. package/dist/tests/exporters/coq/coq-exporter.test.d.ts.map +1 -0
  315. package/dist/tests/exporters/coq/coq-exporter.test.js +353 -0
  316. package/dist/tests/exporters/coq/coq-exporter.test.js.map +1 -0
  317. package/dist/tests/fol-prover/cnf.test.d.ts +2 -0
  318. package/dist/tests/fol-prover/cnf.test.d.ts.map +1 -0
  319. package/dist/tests/fol-prover/cnf.test.js +74 -0
  320. package/dist/tests/fol-prover/cnf.test.js.map +1 -0
  321. package/dist/tests/fol-prover/prove.test.d.ts +2 -0
  322. package/dist/tests/fol-prover/prove.test.d.ts.map +1 -0
  323. package/dist/tests/fol-prover/prove.test.js +106 -0
  324. package/dist/tests/fol-prover/prove.test.js.map +1 -0
  325. package/dist/tests/fol-prover/unify.test.d.ts +2 -0
  326. package/dist/tests/fol-prover/unify.test.d.ts.map +1 -0
  327. package/dist/tests/fol-prover/unify.test.js +66 -0
  328. package/dist/tests/fol-prover/unify.test.js.map +1 -0
  329. package/dist/tests/hyperreal/hyperreal.test.d.ts +2 -0
  330. package/dist/tests/hyperreal/hyperreal.test.d.ts.map +1 -0
  331. package/dist/tests/hyperreal/hyperreal.test.js +219 -0
  332. package/dist/tests/hyperreal/hyperreal.test.js.map +1 -0
  333. package/dist/tests/lsp/server.test.d.ts +2 -0
  334. package/dist/tests/lsp/server.test.d.ts.map +1 -0
  335. package/dist/tests/lsp/server.test.js +406 -0
  336. package/dist/tests/lsp/server.test.js.map +1 -0
  337. package/dist/tests/memo/cache.test.d.ts +2 -0
  338. package/dist/tests/memo/cache.test.d.ts.map +1 -0
  339. package/dist/tests/memo/cache.test.js +252 -0
  340. package/dist/tests/memo/cache.test.js.map +1 -0
  341. package/dist/tests/parallel/parallel-pool.test.d.ts +11 -0
  342. package/dist/tests/parallel/parallel-pool.test.d.ts.map +1 -0
  343. package/dist/tests/parallel/parallel-pool.test.js +192 -0
  344. package/dist/tests/parallel/parallel-pool.test.js.map +1 -0
  345. package/dist/tests/plugin-system/demo-min-logic.test.d.ts +2 -0
  346. package/dist/tests/plugin-system/demo-min-logic.test.d.ts.map +1 -0
  347. package/dist/tests/plugin-system/demo-min-logic.test.js +85 -0
  348. package/dist/tests/plugin-system/demo-min-logic.test.js.map +1 -0
  349. package/dist/tests/plugin-system/registry.test.d.ts +2 -0
  350. package/dist/tests/plugin-system/registry.test.d.ts.map +1 -0
  351. package/dist/tests/plugin-system/registry.test.js +88 -0
  352. package/dist/tests/plugin-system/registry.test.js.map +1 -0
  353. package/dist/tests/plugin-system/validate.test.d.ts +2 -0
  354. package/dist/tests/plugin-system/validate.test.d.ts.map +1 -0
  355. package/dist/tests/plugin-system/validate.test.js +101 -0
  356. package/dist/tests/plugin-system/validate.test.js.map +1 -0
  357. package/dist/tests/proof-exchange/proof-exchange.test.d.ts +2 -0
  358. package/dist/tests/proof-exchange/proof-exchange.test.d.ts.map +1 -0
  359. package/dist/tests/proof-exchange/proof-exchange.test.js +161 -0
  360. package/dist/tests/proof-exchange/proof-exchange.test.js.map +1 -0
  361. package/dist/tests/sat-v2/clause-learning.test.d.ts +2 -0
  362. package/dist/tests/sat-v2/clause-learning.test.d.ts.map +1 -0
  363. package/dist/tests/sat-v2/clause-learning.test.js +73 -0
  364. package/dist/tests/sat-v2/clause-learning.test.js.map +1 -0
  365. package/dist/tests/sat-v2/lbd.test.d.ts +2 -0
  366. package/dist/tests/sat-v2/lbd.test.d.ts.map +1 -0
  367. package/dist/tests/sat-v2/lbd.test.js +82 -0
  368. package/dist/tests/sat-v2/lbd.test.js.map +1 -0
  369. package/dist/tests/sat-v2/luby.test.d.ts +2 -0
  370. package/dist/tests/sat-v2/luby.test.d.ts.map +1 -0
  371. package/dist/tests/sat-v2/luby.test.js +58 -0
  372. package/dist/tests/sat-v2/luby.test.js.map +1 -0
  373. package/dist/tests/sat-v2/phase-saving.test.d.ts +2 -0
  374. package/dist/tests/sat-v2/phase-saving.test.d.ts.map +1 -0
  375. package/dist/tests/sat-v2/phase-saving.test.js +38 -0
  376. package/dist/tests/sat-v2/phase-saving.test.js.map +1 -0
  377. package/dist/tests/sat-v2/solver-end-to-end.test.d.ts +2 -0
  378. package/dist/tests/sat-v2/solver-end-to-end.test.d.ts.map +1 -0
  379. package/dist/tests/sat-v2/solver-end-to-end.test.js +199 -0
  380. package/dist/tests/sat-v2/solver-end-to-end.test.js.map +1 -0
  381. package/dist/tests/sat-v2/vsids.test.d.ts +2 -0
  382. package/dist/tests/sat-v2/vsids.test.d.ts.map +1 -0
  383. package/dist/tests/sat-v2/vsids.test.js +69 -0
  384. package/dist/tests/sat-v2/vsids.test.js.map +1 -0
  385. package/dist/tests/smt/mock-backend.test.d.ts +2 -0
  386. package/dist/tests/smt/mock-backend.test.d.ts.map +1 -0
  387. package/dist/tests/smt/mock-backend.test.js +129 -0
  388. package/dist/tests/smt/mock-backend.test.js.map +1 -0
  389. package/dist/tests/smt/serializer.test.d.ts +2 -0
  390. package/dist/tests/smt/serializer.test.d.ts.map +1 -0
  391. package/dist/tests/smt/serializer.test.js +94 -0
  392. package/dist/tests/smt/serializer.test.js.map +1 -0
  393. package/dist/tests/smt/subprocess-backend.test.d.ts +2 -0
  394. package/dist/tests/smt/subprocess-backend.test.d.ts.map +1 -0
  395. package/dist/tests/smt/subprocess-backend.test.js +89 -0
  396. package/dist/tests/smt/subprocess-backend.test.js.map +1 -0
  397. package/dist/tests/streaming/stream-eval.test.d.ts +2 -0
  398. package/dist/tests/streaming/stream-eval.test.d.ts.map +1 -0
  399. package/dist/tests/streaming/stream-eval.test.js +170 -0
  400. package/dist/tests/streaming/stream-eval.test.js.map +1 -0
  401. package/dist/tests/text-layer-v2/claim-graph.test.d.ts +2 -0
  402. package/dist/tests/text-layer-v2/claim-graph.test.d.ts.map +1 -0
  403. package/dist/tests/text-layer-v2/claim-graph.test.js +255 -0
  404. package/dist/tests/text-layer-v2/claim-graph.test.js.map +1 -0
  405. package/dist/tests/time-travel/snapshot.test.d.ts +2 -0
  406. package/dist/tests/time-travel/snapshot.test.d.ts.map +1 -0
  407. package/dist/tests/time-travel/snapshot.test.js +75 -0
  408. package/dist/tests/time-travel/snapshot.test.js.map +1 -0
  409. package/dist/tests/time-travel/store.test.d.ts +2 -0
  410. package/dist/tests/time-travel/store.test.d.ts.map +1 -0
  411. package/dist/tests/time-travel/store.test.js +242 -0
  412. package/dist/tests/time-travel/store.test.js.map +1 -0
  413. package/dist/tests/typecheck-core.test.d.ts +2 -0
  414. package/dist/tests/typecheck-core.test.d.ts.map +1 -0
  415. package/dist/tests/typecheck-core.test.js +339 -0
  416. package/dist/tests/typecheck-core.test.js.map +1 -0
  417. package/dist/text-layer/v2/claim-graph.d.ts +45 -0
  418. package/dist/text-layer/v2/claim-graph.d.ts.map +1 -0
  419. package/dist/text-layer/v2/claim-graph.js +270 -0
  420. package/dist/text-layer/v2/claim-graph.js.map +1 -0
  421. package/dist/text-layer/v2/index.d.ts +6 -0
  422. package/dist/text-layer/v2/index.d.ts.map +1 -0
  423. package/dist/text-layer/v2/index.js +10 -0
  424. package/dist/text-layer/v2/index.js.map +1 -0
  425. package/dist/text-layer/v2/types.d.ts +32 -0
  426. package/dist/text-layer/v2/types.d.ts.map +1 -0
  427. package/dist/text-layer/v2/types.js +11 -0
  428. package/dist/text-layer/v2/types.js.map +1 -0
  429. package/dist/time-travel/index.d.ts +4 -0
  430. package/dist/time-travel/index.d.ts.map +1 -0
  431. package/dist/time-travel/index.js +8 -0
  432. package/dist/time-travel/index.js.map +1 -0
  433. package/dist/time-travel/snapshot.d.ts +9 -0
  434. package/dist/time-travel/snapshot.d.ts.map +1 -0
  435. package/dist/time-travel/snapshot.js +24 -0
  436. package/dist/time-travel/snapshot.js.map +1 -0
  437. package/dist/time-travel/store.d.ts +14 -0
  438. package/dist/time-travel/store.d.ts.map +1 -0
  439. package/dist/time-travel/store.js +119 -0
  440. package/dist/time-travel/store.js.map +1 -0
  441. package/dist/time-travel/types.d.ts +50 -0
  442. package/dist/time-travel/types.d.ts.map +1 -0
  443. package/dist/time-travel/types.js +3 -0
  444. package/dist/time-travel/types.js.map +1 -0
  445. package/package.json +5 -1
@@ -1,57 +1,47 @@
1
1
  "use strict";
2
2
  /**
3
3
  * ST Parser — Parser recursivo descendente
4
+ *
5
+ * Refactor α2 (V4): el parser monolitico se descompone en modulos.
6
+ * - ./state.ts — ParserState: token cursor + diagnostico
7
+ * - ./formulas.ts — precedencia de formulas + MODAL_ALIASES + formulaToString
8
+ *
9
+ * La clase `Parser` es el facade publico: misma firma de constructor,
10
+ * mismo `parse(source): Program`, mismo `diagnostics`. Los consumidores
11
+ * (interpreter, cli, api, protocol/handler) NO cambian.
4
12
  */
5
13
  Object.defineProperty(exports, "__esModule", { value: true });
6
14
  exports.Parser = void 0;
7
15
  const tokens_1 = require("../lexer/tokens");
8
16
  const lexer_1 = require("../lexer/lexer");
9
17
  const compat_1 = require("../runtime/compat");
10
- // Modal aliases per profile: maps identifier names to modal formula types
11
- const MODAL_ALIASES = {
12
- 'deontic.standard': { O: 'box', P: 'diamond', F: 'box_not' },
13
- 'epistemic.s5': { K: 'box', B: 'diamond' },
14
- 'temporal.ltl': { G: 'box', F: 'diamond' },
15
- 'modal.k': { Box: 'box', Dia: 'diamond' },
16
- 'modal.s4': { Box: 'box', Dia: 'diamond' },
17
- 'modal.s5': { Box: 'box', Dia: 'diamond' },
18
- 'modal.t': { Box: 'box', Dia: 'diamond' },
19
- };
18
+ const state_1 = require("./state");
19
+ const formulas_1 = require("./formulas");
20
20
  class Parser {
21
- tokens = [];
22
- pos = 0;
23
- file;
24
- diagnostics = [];
25
- contextStack = [];
26
- knownFunctionNames = new Set([
27
- 'typeof',
28
- 'is_valid',
29
- 'is_satisfiable',
30
- 'get_atoms',
31
- 'atoms_of',
32
- 'len',
33
- 'at',
34
- 'formula_eq',
35
- 'input',
36
- ]);
37
- knownTheoryNames = new Set();
38
- currentProfile = '';
21
+ state;
39
22
  initialProfile;
40
23
  constructor(file = '<stdin>', profile) {
41
- this.file = file;
24
+ this.state = new state_1.ParserState(file);
42
25
  this.initialProfile = profile;
43
26
  }
27
+ // --- Acceso compatible al estado (diagnostics expuesto como antes) ---
28
+ get diagnostics() {
29
+ return this.state.diagnostics;
30
+ }
31
+ set diagnostics(value) {
32
+ this.state.diagnostics = value;
33
+ }
44
34
  parse(source) {
45
35
  const normalizedSource = (0, compat_1.normalizeSTSource)(source);
46
- const lexer = new lexer_1.Lexer(normalizedSource, this.file, this.initialProfile);
47
- this.tokens = lexer.tokenize();
48
- this.diagnostics.push(...lexer.diagnostics);
49
- this.pos = 0;
50
- this.contextStack = [];
36
+ const lexer = new lexer_1.Lexer(normalizedSource, this.state.file, this.initialProfile);
37
+ this.state.tokens = lexer.tokenize();
38
+ this.state.diagnostics.push(...lexer.diagnostics);
39
+ this.state.pos = 0;
40
+ this.state.contextStack = [];
51
41
  const statements = [];
52
- while (!this.isAtEnd()) {
53
- this.skipNewlines();
54
- if (this.isAtEnd())
42
+ while (!this.state.isAtEnd()) {
43
+ this.state.skipNewlines();
44
+ if (this.state.isAtEnd())
55
45
  break;
56
46
  try {
57
47
  const stmt = this.parseStatement();
@@ -61,34 +51,29 @@ class Parser {
61
51
  }
62
52
  catch (e) {
63
53
  const message = e instanceof Error ? e.message : 'Error de parseo inesperado';
64
- this.diagnostics.push({
65
- severity: 'error',
66
- message,
67
- file: this.file,
68
- line: this.current().line,
69
- column: this.current().column,
70
- });
54
+ this.state.pushDiagnostic('error', message);
71
55
  this.advanceToNextStatement();
72
56
  }
73
57
  }
74
- return { statements, file: this.file };
58
+ return { statements, file: this.state.file };
75
59
  }
76
60
  // --- Parsing de statements ---
77
61
  parseStatement() {
78
- const tok = this.current();
62
+ const s = this.state;
63
+ const tok = s.current();
79
64
  // Detección de llamada a función: nombre(...)
80
- if (this.peek(1) === tokens_1.TokenType.LPAREN &&
81
- (tok.type === tokens_1.TokenType.IDENTIFIER || this.knownFunctionNames.has(tok.value))) {
82
- return this.withContext(`llamada a funcion '${tok.value}'`, () => this.parseFnCall());
65
+ if (s.peek(1) === tokens_1.TokenType.LPAREN &&
66
+ (tok.type === tokens_1.TokenType.IDENTIFIER || s.knownFunctionNames.has(tok.value))) {
67
+ return s.withContext(`llamada a funcion '${tok.value}'`, () => this.parseFnCall());
83
68
  }
84
69
  // Detección de llamada a método: objeto.metodo(...)
85
70
  if (tok.type === tokens_1.TokenType.IDENTIFIER &&
86
- this.peek(1) === tokens_1.TokenType.DOT &&
87
- this.peek(2) === tokens_1.TokenType.IDENTIFIER &&
88
- this.peek(3) === tokens_1.TokenType.LPAREN) {
89
- return this.withContext(`llamada a metodo '${tok.value}'`, () => this.parseMemberFnCall());
71
+ s.peek(1) === tokens_1.TokenType.DOT &&
72
+ s.peek(2) === tokens_1.TokenType.IDENTIFIER &&
73
+ s.peek(3) === tokens_1.TokenType.LPAREN) {
74
+ return s.withContext(`llamada a metodo '${tok.value}'`, () => this.parseMemberFnCall());
90
75
  }
91
- return this.withContext(this.describeStatementContext(tok), () => {
76
+ return s.withContext(this.describeStatementContext(tok), () => {
92
77
  switch (tok.type) {
93
78
  case tokens_1.TokenType.LOGIC:
94
79
  return this.parseLogicDecl();
@@ -158,72 +143,76 @@ class Parser {
158
143
  case tokens_1.TokenType.GLOSSARY:
159
144
  return this.parseGlossaryCmd();
160
145
  case tokens_1.TokenType.IDENTIFIER:
161
- throw new Error(this.contextualize(`Statement inesperado: '${tok.value}' (${tok.type})`));
146
+ throw new Error(s.contextualize(`Statement inesperado: '${tok.value}' (${tok.type})`));
162
147
  case tokens_1.TokenType.NEWLINE:
163
- this.advance();
148
+ s.advance();
164
149
  return null;
165
150
  case tokens_1.TokenType.EOF:
166
151
  return null;
167
152
  default:
168
- throw new Error(this.contextualize(`Statement inesperado: '${tok.value}' (${tok.type})`));
153
+ throw new Error(s.contextualize(`Statement inesperado: '${tok.value}' (${tok.type})`));
169
154
  }
170
155
  });
171
156
  }
172
157
  // logic classical.propositional
173
158
  parseLogicDecl() {
174
- const src = this.loc();
175
- this.expect(tokens_1.TokenType.LOGIC);
176
- // Leer perfil como secuencia de ID.ID
177
- let profile = this.expectIdent();
178
- while (this.match(tokens_1.TokenType.DOT)) {
159
+ const s = this.state;
160
+ const src = s.loc();
161
+ s.expect(tokens_1.TokenType.LOGIC);
162
+ let profile = s.expectIdent();
163
+ while (s.match(tokens_1.TokenType.DOT)) {
179
164
  profile += '.';
180
- profile += this.expectIdent();
165
+ profile += s.expectIdent();
181
166
  }
182
- this.currentProfile = profile;
167
+ s.currentProfile = profile;
183
168
  return { kind: 'logic_decl', profile, source: src };
184
169
  }
185
170
  // axiom name = FORMULA o axiom name : FORMULA
186
171
  parseAxiomDecl() {
187
- const src = this.loc();
188
- this.expect(tokens_1.TokenType.AXIOM);
189
- const name = this.expectIdent();
190
- this.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
172
+ const s = this.state;
173
+ const src = s.loc();
174
+ s.expect(tokens_1.TokenType.AXIOM);
175
+ const name = s.expectIdent();
176
+ s.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
191
177
  const formula = this.parseFormula();
192
178
  return { kind: 'axiom_decl', name, formula, source: src };
193
179
  }
194
180
  // theorem name = FORMULA o theorem name : FORMULA
195
181
  parseTheoremDecl() {
196
- const src = this.loc();
197
- this.expect(tokens_1.TokenType.THEOREM);
198
- const name = this.expectIdent();
199
- this.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
182
+ const s = this.state;
183
+ const src = s.loc();
184
+ s.expect(tokens_1.TokenType.THEOREM);
185
+ const name = s.expectIdent();
186
+ s.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
200
187
  const formula = this.parseFormula();
201
188
  return { kind: 'theorem_decl', name, formula, source: src };
202
189
  }
203
190
  // derive FORMULA from {a1, a2, ...}
204
191
  parseDeriveCmd() {
205
- const src = this.loc();
206
- this.expect(tokens_1.TokenType.DERIVE);
192
+ const s = this.state;
193
+ const src = s.loc();
194
+ s.expect(tokens_1.TokenType.DERIVE);
207
195
  const goal = this.parseFormula();
208
- this.expect(tokens_1.TokenType.FROM);
209
- const premises = this.parseIdList();
196
+ s.expect(tokens_1.TokenType.FROM);
197
+ const premises = (0, formulas_1.parseIdList)(s);
210
198
  return { kind: 'derive_cmd', goal, premises, source: src };
211
199
  }
212
200
  // check valid FORMULA | check satisfiable FORMULA | check equivalent F, F
213
201
  parseCheckCmd() {
214
- const src = this.loc();
215
- this.expect(tokens_1.TokenType.CHECK);
216
- if (this.match(tokens_1.TokenType.VALID)) {
202
+ const s = this.state;
203
+ const src = s.loc();
204
+ s.expect(tokens_1.TokenType.CHECK);
205
+ if (s.match(tokens_1.TokenType.VALID)) {
217
206
  const formula = this.parseFormula();
218
207
  return { kind: 'check_valid_cmd', formula, source: src };
219
208
  }
220
- if (this.match(tokens_1.TokenType.SATISFIABLE)) {
209
+ if (s.match(tokens_1.TokenType.SATISFIABLE)) {
221
210
  const formula = this.parseFormula();
222
211
  return { kind: 'check_satisfiable_cmd', formula, source: src };
223
212
  }
224
- if (this.match(tokens_1.TokenType.EQUIVALENT)) {
213
+ if (s.match(tokens_1.TokenType.EQUIVALENT)) {
225
214
  const left = this.parseFormula();
226
- this.expect(tokens_1.TokenType.COMMA);
215
+ s.expect(tokens_1.TokenType.COMMA);
227
216
  const right = this.parseFormula();
228
217
  return { kind: 'check_equivalent_cmd', left, right, source: src };
229
218
  }
@@ -231,98 +220,96 @@ class Parser {
231
220
  }
232
221
  // prove FORMULA [from {a1, a2}]
233
222
  parseProveCmd() {
234
- const src = this.loc();
235
- this.expect(tokens_1.TokenType.PROVE);
223
+ const s = this.state;
224
+ const src = s.loc();
225
+ s.expect(tokens_1.TokenType.PROVE);
236
226
  const goal = this.parseFormula();
237
- // 'from' is optional — if omitted, prove from entire theory
238
227
  let premises = [];
239
- if (this.match(tokens_1.TokenType.FROM)) {
240
- premises = this.parseIdList();
228
+ if (s.match(tokens_1.TokenType.FROM)) {
229
+ premises = (0, formulas_1.parseIdList)(s);
241
230
  }
242
231
  return { kind: 'prove_cmd', goal, premises, source: src };
243
232
  }
244
233
  // countermodel FORMULA | refute FORMULA
245
234
  parseCountermodelCmd() {
246
- const src = this.loc();
247
- // Acepta tanto 'countermodel' como 'refute'
248
- if (this.checkType(tokens_1.TokenType.COUNTERMODEL)) {
249
- this.advance();
235
+ const s = this.state;
236
+ const src = s.loc();
237
+ if (s.checkType(tokens_1.TokenType.COUNTERMODEL)) {
238
+ s.advance();
250
239
  }
251
240
  else {
252
- this.expect(tokens_1.TokenType.REFUTE);
241
+ s.expect(tokens_1.TokenType.REFUTE);
253
242
  }
254
243
  const formula = this.parseFormula();
255
244
  return { kind: 'countermodel_cmd', formula, source: src };
256
245
  }
257
246
  // truth_table FORMULA
258
247
  parseTruthTableCmd() {
259
- const src = this.loc();
260
- this.expect(tokens_1.TokenType.TRUTH_TABLE);
248
+ const s = this.state;
249
+ const src = s.loc();
250
+ s.expect(tokens_1.TokenType.TRUTH_TABLE);
261
251
  const formula = this.parseFormula();
262
252
  return { kind: 'truth_table_cmd', formula, source: src };
263
253
  }
264
254
  // let name = passage([[path#anchor]])
265
255
  // let name = formalize passageName as FORMULA
266
256
  parseLetDecl() {
267
- const src = this.loc();
268
- this.expect(tokens_1.TokenType.LET);
269
- const name = this.expectIdent();
270
- this.expect(tokens_1.TokenType.EQUALS);
257
+ const s = this.state;
258
+ const src = s.loc();
259
+ s.expect(tokens_1.TokenType.LET);
260
+ const name = s.expectIdent();
261
+ s.expect(tokens_1.TokenType.EQUALS);
271
262
  if (this.canStartActionExpr()) {
272
263
  const action = this.parseActionExpr();
273
264
  return { kind: 'let_decl', name, letType: 'action', action, source: src };
274
265
  }
275
- if (this.match(tokens_1.TokenType.PASSAGE)) {
266
+ if (s.match(tokens_1.TokenType.PASSAGE)) {
276
267
  // passage @Source "text" (standalone passage with source and raw text)
277
- if (this.checkType(tokens_1.TokenType.AT)) {
278
- this.advance(); // skip @
279
- const sourceRef = this.expectName();
280
- // Optional section: §section or just a string
268
+ if (s.checkType(tokens_1.TokenType.AT)) {
269
+ s.advance(); // skip @
270
+ const sourceRef = s.expectName();
281
271
  let section = '';
282
- if (this.checkType(tokens_1.TokenType.STRING)) {
272
+ if (s.checkType(tokens_1.TokenType.STRING)) {
283
273
  // No section, just text
284
274
  }
285
- else if (this.checkType(tokens_1.TokenType.IDENTIFIER) || this.checkType(tokens_1.TokenType.NUMBER)) {
286
- section = this.current().value;
287
- this.advance();
275
+ else if (s.checkType(tokens_1.TokenType.IDENTIFIER) || s.checkType(tokens_1.TokenType.NUMBER)) {
276
+ section = s.current().value;
277
+ s.advance();
288
278
  }
289
- if (this.checkType(tokens_1.TokenType.STRING)) {
290
- this.advance(); // consume the raw text string
279
+ if (s.checkType(tokens_1.TokenType.STRING)) {
280
+ s.advance();
291
281
  const anchorPath = `@${sourceRef}${section ? '#' + section : ''}`;
292
282
  return { kind: 'let_decl', name, letType: 'passage', anchorPath, source: src };
293
283
  }
294
284
  }
295
- this.expect(tokens_1.TokenType.LPAREN);
296
- this.expect(tokens_1.TokenType.LBRACKET_DOUBLE);
297
- // El lexer ya leyó el contenido como STRING entre [[ y ]]
285
+ s.expect(tokens_1.TokenType.LPAREN);
286
+ s.expect(tokens_1.TokenType.LBRACKET_DOUBLE);
298
287
  let anchorPath = '';
299
- if (this.checkType(tokens_1.TokenType.STRING)) {
300
- anchorPath = this.current().value;
301
- this.advance();
288
+ if (s.checkType(tokens_1.TokenType.STRING)) {
289
+ anchorPath = s.current().value;
290
+ s.advance();
302
291
  }
303
292
  else {
304
- // Fallback: leer tokens hasta ]]
305
- while (!this.checkType(tokens_1.TokenType.RBRACKET_DOUBLE) && !this.isAtEnd()) {
306
- anchorPath += this.current().value;
307
- this.advance();
293
+ while (!s.checkType(tokens_1.TokenType.RBRACKET_DOUBLE) && !s.isAtEnd()) {
294
+ anchorPath += s.current().value;
295
+ s.advance();
308
296
  }
309
297
  }
310
- this.expect(tokens_1.TokenType.RBRACKET_DOUBLE);
311
- this.expect(tokens_1.TokenType.RPAREN);
298
+ s.expect(tokens_1.TokenType.RBRACKET_DOUBLE);
299
+ s.expect(tokens_1.TokenType.RPAREN);
312
300
  return { kind: 'let_decl', name, letType: 'passage', anchorPath, source: src };
313
301
  }
314
- if (this.match(tokens_1.TokenType.FORMALIZE)) {
315
- const passageName = this.expectIdent();
316
- this.expect(tokens_1.TokenType.AS);
302
+ if (s.match(tokens_1.TokenType.FORMALIZE)) {
303
+ const passageName = s.expectIdent();
304
+ s.expect(tokens_1.TokenType.AS);
317
305
  const formula = this.parseFormula();
318
306
  return { kind: 'let_decl', name, letType: 'formalize', passageName, formula, source: src };
319
307
  }
320
308
  // let name = "texto descriptivo" [: FORMULA]
321
- if (this.checkType(tokens_1.TokenType.STRING)) {
322
- const description = this.current().value;
323
- this.advance();
324
- // Opcionalmente: let name = "desc" : FORMULA
325
- if (this.match(tokens_1.TokenType.COLON)) {
309
+ if (s.checkType(tokens_1.TokenType.STRING)) {
310
+ const description = s.current().value;
311
+ s.advance();
312
+ if (s.match(tokens_1.TokenType.COLON)) {
326
313
  const formula = this.parseFormula();
327
314
  return { kind: 'let_decl', name, letType: 'formula', formula, description, source: src };
328
315
  }
@@ -334,192 +321,194 @@ class Parser {
334
321
  }
335
322
  // claim name = ID_OR_FORMULA
336
323
  parseClaimDecl() {
337
- const src = this.loc();
338
- this.expect(tokens_1.TokenType.CLAIM);
339
- const name = this.expectIdent();
340
- this.expect(tokens_1.TokenType.EQUALS);
341
- // Si es un identificador simple y no tiene paréntesis (no es predicado)
342
- // podría ser una referencia a una formalización o pasaje.
343
- if (this.checkType(tokens_1.TokenType.IDENTIFIER) && this.peek(1) !== tokens_1.TokenType.LPAREN) {
344
- const val = this.current().value;
345
- const saved = this.pos;
346
- this.advance();
347
- // Si después del IDENTIFIER hay un NEWLINE o EOF, es una referencia.
348
- if (this.isAtEnd() || this.checkType(tokens_1.TokenType.NEWLINE)) {
324
+ const s = this.state;
325
+ const src = s.loc();
326
+ s.expect(tokens_1.TokenType.CLAIM);
327
+ const name = s.expectIdent();
328
+ s.expect(tokens_1.TokenType.EQUALS);
329
+ if (s.checkType(tokens_1.TokenType.IDENTIFIER) && s.peek(1) !== tokens_1.TokenType.LPAREN) {
330
+ const val = s.current().value;
331
+ const saved = s.pos;
332
+ s.advance();
333
+ if (s.isAtEnd() || s.checkType(tokens_1.TokenType.NEWLINE)) {
349
334
  return { kind: 'claim_decl', name, value: val, formalization: val, source: src };
350
335
  }
351
- // Si no, backtrack y parsear como formula completa
352
- this.pos = saved;
336
+ s.pos = saved;
353
337
  }
354
338
  const formula = this.parseFormula();
355
339
  return {
356
340
  kind: 'claim_decl',
357
341
  name,
358
- value: this.formulaToString(formula),
342
+ value: (0, formulas_1.formulaToString)(formula),
359
343
  formula,
360
344
  source: src,
361
345
  };
362
346
  }
363
347
  // support claimName <- sourceName
364
348
  parseSupportDecl() {
365
- const src = this.loc();
366
- this.expect(tokens_1.TokenType.SUPPORT);
367
- const claimName = this.expectIdent();
368
- this.expect(tokens_1.TokenType.BACK_ARROW);
369
- const sourceName = this.expectIdent();
349
+ const s = this.state;
350
+ const src = s.loc();
351
+ s.expect(tokens_1.TokenType.SUPPORT);
352
+ const claimName = s.expectIdent();
353
+ s.expect(tokens_1.TokenType.BACK_ARROW);
354
+ const sourceName = s.expectIdent();
370
355
  return { kind: 'support_decl', claimName, sourceName, source: src };
371
356
  }
372
357
  // confidence claimName = NUMBER
373
358
  parseConfidenceDecl() {
374
- const src = this.loc();
375
- this.expect(tokens_1.TokenType.CONFIDENCE);
376
- const claimName = this.expectIdent();
377
- this.expect(tokens_1.TokenType.EQUALS);
378
- const tok = this.expect(tokens_1.TokenType.NUMBER);
359
+ const s = this.state;
360
+ const src = s.loc();
361
+ s.expect(tokens_1.TokenType.CONFIDENCE);
362
+ const claimName = s.expectIdent();
363
+ s.expect(tokens_1.TokenType.EQUALS);
364
+ const tok = s.expect(tokens_1.TokenType.NUMBER);
379
365
  return { kind: 'confidence_decl', claimName, value: parseFloat(tok.value), source: src };
380
366
  }
381
367
  // context claimName = "text"
382
368
  parseContextDecl() {
383
- const src = this.loc();
384
- this.expect(tokens_1.TokenType.CONTEXT);
385
- const claimName = this.expectIdent();
386
- this.expect(tokens_1.TokenType.EQUALS);
387
- const tok = this.expect(tokens_1.TokenType.STRING);
369
+ const s = this.state;
370
+ const src = s.loc();
371
+ s.expect(tokens_1.TokenType.CONTEXT);
372
+ const claimName = s.expectIdent();
373
+ s.expect(tokens_1.TokenType.EQUALS);
374
+ const tok = s.expect(tokens_1.TokenType.STRING);
388
375
  return { kind: 'context_decl', claimName, text: tok.value, source: src };
389
376
  }
390
377
  // render target [as FORMAT] | render glossary [as FORMAT] | render analysis [as FORMAT]
391
378
  parseRenderCmd() {
392
- const src = this.loc();
393
- this.expect(tokens_1.TokenType.RENDER);
394
- // El target puede ser un identificador, keyword 'theory', 'glossary', o 'analysis'
379
+ const s = this.state;
380
+ const src = s.loc();
381
+ s.expect(tokens_1.TokenType.RENDER);
395
382
  let target;
396
- if (this.checkType(tokens_1.TokenType.THEORY)) {
397
- target = this.current().value;
398
- this.advance();
383
+ if (s.checkType(tokens_1.TokenType.THEORY)) {
384
+ target = s.current().value;
385
+ s.advance();
399
386
  }
400
- else if (this.checkType(tokens_1.TokenType.GLOSSARY)) {
387
+ else if (s.checkType(tokens_1.TokenType.GLOSSARY)) {
401
388
  target = 'glossary';
402
- this.advance();
389
+ s.advance();
403
390
  }
404
391
  else {
405
- target = this.expectIdent();
392
+ target = s.expectIdent();
406
393
  }
407
394
  let format = 'markdown';
408
- // render X as FORMAT
409
- if (this.match(tokens_1.TokenType.AS)) {
410
- if (this.checkType(tokens_1.TokenType.IDENTIFIER)) {
411
- format = this.current().value;
412
- this.advance();
395
+ if (s.match(tokens_1.TokenType.AS)) {
396
+ if (s.checkType(tokens_1.TokenType.IDENTIFIER)) {
397
+ format = s.current().value;
398
+ s.advance();
413
399
  }
414
400
  }
415
- else if (this.checkType(tokens_1.TokenType.IDENTIFIER)) {
416
- // Backward compatible: render X markdown
417
- format = this.current().value;
418
- this.advance();
401
+ else if (s.checkType(tokens_1.TokenType.IDENTIFIER)) {
402
+ format = s.current().value;
403
+ s.advance();
419
404
  }
420
405
  return { kind: 'render_cmd', target, format, source: src };
421
406
  }
422
407
  // analyze {P1, P2, ...} -> CONCLUSION
423
408
  parseAnalyzeCmd() {
424
- const src = this.loc();
425
- this.expect(tokens_1.TokenType.ANALYZE);
426
- this.expect(tokens_1.TokenType.LBRACE);
409
+ const s = this.state;
410
+ const src = s.loc();
411
+ s.expect(tokens_1.TokenType.ANALYZE);
412
+ s.expect(tokens_1.TokenType.LBRACE);
427
413
  const premises = [];
428
- if (!this.checkType(tokens_1.TokenType.RBRACE)) {
414
+ if (!s.checkType(tokens_1.TokenType.RBRACE)) {
429
415
  premises.push(this.parseFormula());
430
- while (this.match(tokens_1.TokenType.COMMA)) {
416
+ while (s.match(tokens_1.TokenType.COMMA)) {
431
417
  premises.push(this.parseFormula());
432
418
  }
433
419
  }
434
- this.expect(tokens_1.TokenType.RBRACE);
435
- this.expect(tokens_1.TokenType.ARROW);
420
+ s.expect(tokens_1.TokenType.RBRACE);
421
+ s.expect(tokens_1.TokenType.ARROW);
436
422
  const conclusion = this.parseFormula();
437
423
  return { kind: 'analyze_cmd', premises, conclusion, source: src };
438
424
  }
439
425
  // explain FORMULA
440
426
  parseExplainCmd() {
441
- const src = this.loc();
442
- this.expect(tokens_1.TokenType.EXPLAIN);
427
+ const s = this.state;
428
+ const src = s.loc();
429
+ s.expect(tokens_1.TokenType.EXPLAIN);
443
430
  const formula = this.parseFormula();
444
431
  return { kind: 'explain_cmd', formula, source: src };
445
432
  }
446
433
  canStartActionExpr() {
447
- return (this.checkType(tokens_1.TokenType.CHECK) ||
448
- this.checkType(tokens_1.TokenType.DERIVE) ||
449
- this.checkType(tokens_1.TokenType.PROVE) ||
450
- this.checkType(tokens_1.TokenType.COUNTERMODEL) ||
451
- this.checkType(tokens_1.TokenType.REFUTE) ||
452
- this.checkType(tokens_1.TokenType.TRUTH_TABLE) ||
453
- this.checkType(tokens_1.TokenType.EXPLAIN));
434
+ const s = this.state;
435
+ return (s.checkType(tokens_1.TokenType.CHECK) ||
436
+ s.checkType(tokens_1.TokenType.DERIVE) ||
437
+ s.checkType(tokens_1.TokenType.PROVE) ||
438
+ s.checkType(tokens_1.TokenType.COUNTERMODEL) ||
439
+ s.checkType(tokens_1.TokenType.REFUTE) ||
440
+ s.checkType(tokens_1.TokenType.TRUTH_TABLE) ||
441
+ s.checkType(tokens_1.TokenType.EXPLAIN));
454
442
  }
455
443
  parseActionExpr() {
456
- const src = this.loc();
457
- if (this.match(tokens_1.TokenType.CHECK)) {
458
- if (this.match(tokens_1.TokenType.VALID)) {
444
+ const s = this.state;
445
+ const src = s.loc();
446
+ if (s.match(tokens_1.TokenType.CHECK)) {
447
+ if (s.match(tokens_1.TokenType.VALID)) {
459
448
  const formula = this.parseFormula();
460
449
  return { kind: 'action_expr', action: 'check_valid', formula, source: src };
461
450
  }
462
- if (this.match(tokens_1.TokenType.SATISFIABLE)) {
451
+ if (s.match(tokens_1.TokenType.SATISFIABLE)) {
463
452
  const formula = this.parseFormula();
464
453
  return { kind: 'action_expr', action: 'check_satisfiable', formula, source: src };
465
454
  }
466
- if (this.match(tokens_1.TokenType.EQUIVALENT)) {
455
+ if (s.match(tokens_1.TokenType.EQUIVALENT)) {
467
456
  const left = this.parseFormula();
468
- this.expect(tokens_1.TokenType.COMMA);
457
+ s.expect(tokens_1.TokenType.COMMA);
469
458
  const right = this.parseFormula();
470
459
  return { kind: 'action_expr', action: 'check_equivalent', left, right, source: src };
471
460
  }
472
461
  throw new Error(`Se esperaba 'valid', 'satisfiable' o 'equivalent' despues de 'check'`);
473
462
  }
474
- if (this.match(tokens_1.TokenType.DERIVE)) {
463
+ if (s.match(tokens_1.TokenType.DERIVE)) {
475
464
  const goal = this.parseFormula();
476
- this.expect(tokens_1.TokenType.FROM);
477
- const premises = this.parseIdList();
465
+ s.expect(tokens_1.TokenType.FROM);
466
+ const premises = (0, formulas_1.parseIdList)(s);
478
467
  return { kind: 'action_expr', action: 'derive', goal, premises, source: src };
479
468
  }
480
- if (this.match(tokens_1.TokenType.PROVE)) {
469
+ if (s.match(tokens_1.TokenType.PROVE)) {
481
470
  const goal = this.parseFormula();
482
- this.expect(tokens_1.TokenType.FROM);
483
- const premises = this.parseIdList();
471
+ s.expect(tokens_1.TokenType.FROM);
472
+ const premises = (0, formulas_1.parseIdList)(s);
484
473
  return { kind: 'action_expr', action: 'prove', goal, premises, source: src };
485
474
  }
486
- if (this.checkType(tokens_1.TokenType.COUNTERMODEL)) {
487
- this.advance();
475
+ if (s.checkType(tokens_1.TokenType.COUNTERMODEL)) {
476
+ s.advance();
488
477
  const formula = this.parseFormula();
489
478
  return { kind: 'action_expr', action: 'countermodel', formula, source: src };
490
479
  }
491
- if (this.match(tokens_1.TokenType.REFUTE)) {
480
+ if (s.match(tokens_1.TokenType.REFUTE)) {
492
481
  const formula = this.parseFormula();
493
482
  return { kind: 'action_expr', action: 'countermodel', formula, source: src };
494
483
  }
495
- if (this.match(tokens_1.TokenType.TRUTH_TABLE)) {
484
+ if (s.match(tokens_1.TokenType.TRUTH_TABLE)) {
496
485
  const formula = this.parseFormula();
497
486
  return { kind: 'action_expr', action: 'truth_table', formula, source: src };
498
487
  }
499
- if (this.match(tokens_1.TokenType.EXPLAIN)) {
488
+ if (s.match(tokens_1.TokenType.EXPLAIN)) {
500
489
  const formula = this.parseFormula();
501
490
  return { kind: 'action_expr', action: 'explain', formula, source: src };
502
491
  }
503
- throw new Error(`Se esperaba una acción capturable, encontrado '${this.current().value}'`);
492
+ throw new Error(`Se esperaba una acción capturable, encontrado '${s.current().value}'`);
504
493
  }
505
494
  // import "path/to/file.st" | import path/to/file
506
495
  parseImportDecl() {
507
- const src = this.loc();
508
- this.expect(tokens_1.TokenType.IMPORT);
509
- // Acepta string entrecomillado o secuencia de ident.ident/ident
496
+ const s = this.state;
497
+ const src = s.loc();
498
+ s.expect(tokens_1.TokenType.IMPORT);
510
499
  let path;
511
- if (this.checkType(tokens_1.TokenType.STRING)) {
512
- path = this.current().value;
513
- this.advance();
500
+ if (s.checkType(tokens_1.TokenType.STRING)) {
501
+ path = s.current().value;
502
+ s.advance();
514
503
  }
515
504
  else {
516
- path = this.expectIdent();
517
- while (this.checkType(tokens_1.TokenType.DOT) || this.checkType(tokens_1.TokenType.IDENTIFIER)) {
518
- if (this.match(tokens_1.TokenType.DOT)) {
505
+ path = s.expectIdent();
506
+ while (s.checkType(tokens_1.TokenType.DOT) || s.checkType(tokens_1.TokenType.IDENTIFIER)) {
507
+ if (s.match(tokens_1.TokenType.DOT)) {
519
508
  path += '.';
520
- if (this.checkType(tokens_1.TokenType.IDENTIFIER)) {
521
- path += this.current().value;
522
- this.advance();
509
+ if (s.checkType(tokens_1.TokenType.IDENTIFIER)) {
510
+ path += s.current().value;
511
+ s.advance();
523
512
  }
524
513
  }
525
514
  else {
@@ -531,85 +520,73 @@ class Parser {
531
520
  }
532
521
  // assume name : FORMULA\n ... \n show FORMULA\n ... \n qed
533
522
  parseProofBlock() {
534
- const src = this.loc();
523
+ const s = this.state;
524
+ const src = s.loc();
535
525
  const assumptions = [];
536
- // Parsear una o más assumptions
537
- while (this.checkType(tokens_1.TokenType.ASSUME)) {
538
- this.advance();
539
- const name = this.expectIdent();
540
- this.expectOneOf(tokens_1.TokenType.COLON, tokens_1.TokenType.EQUALS);
526
+ while (s.checkType(tokens_1.TokenType.ASSUME)) {
527
+ s.advance();
528
+ const name = s.expectIdent();
529
+ s.expectOneOf(tokens_1.TokenType.COLON, tokens_1.TokenType.EQUALS);
541
530
  const formula = this.parseFormula();
542
531
  assumptions.push({ name, formula });
543
- this.skipNewlines();
532
+ s.skipNewlines();
544
533
  }
545
- // Esperar 'show FORMULA'
546
- this.expect(tokens_1.TokenType.SHOW);
534
+ s.expect(tokens_1.TokenType.SHOW);
547
535
  const goal = this.parseFormula();
548
- this.skipNewlines();
549
- // Parsear body statements hasta 'qed'
536
+ s.skipNewlines();
550
537
  const body = [];
551
- while (!this.checkType(tokens_1.TokenType.QED) && !this.isAtEnd()) {
552
- this.skipNewlines();
553
- if (this.checkType(tokens_1.TokenType.QED))
538
+ while (!s.checkType(tokens_1.TokenType.QED) && !s.isAtEnd()) {
539
+ s.skipNewlines();
540
+ if (s.checkType(tokens_1.TokenType.QED))
554
541
  break;
555
542
  try {
556
- const stmt = this.checkType(tokens_1.TokenType.ASSUME)
557
- ? this.parseProofBlock()
558
- : this.parseStatement();
543
+ const stmt = s.checkType(tokens_1.TokenType.ASSUME) ? this.parseProofBlock() : this.parseStatement();
559
544
  if (stmt)
560
545
  body.push(stmt);
561
546
  }
562
547
  catch (e) {
563
548
  const message = e instanceof Error ? e.message : 'Error de parseo en bloque de prueba';
564
- this.diagnostics.push({
565
- severity: 'error',
566
- message,
567
- file: this.file,
568
- line: this.current().line,
569
- column: this.current().column,
570
- });
549
+ s.pushDiagnostic('error', message);
571
550
  this.advanceToNextStatement();
572
551
  }
573
552
  }
574
- if (this.isAtEnd()) {
553
+ if (s.isAtEnd()) {
575
554
  throw new Error(`Se esperaba 'qed' para cerrar el bloque de prueba abierto en linea ${src.line}, columna ${src.column}`);
576
555
  }
577
- this.expect(tokens_1.TokenType.QED);
556
+ s.expect(tokens_1.TokenType.QED);
578
557
  return { kind: 'proof_block', assumptions, goal, body, source: src };
579
558
  }
580
559
  // theory Name(params) { ... } | theory Name extends Parent { ... }
581
560
  parseTheoryDecl() {
582
- const src = this.loc();
583
- this.expect(tokens_1.TokenType.THEORY);
584
- const name = this.expectName();
585
- this.knownTheoryNames.add(name);
586
- // Parámetros opcionales (constructor): theory Math(n)
561
+ const s = this.state;
562
+ const src = s.loc();
563
+ s.expect(tokens_1.TokenType.THEORY);
564
+ const name = s.expectName();
565
+ s.knownTheoryNames.add(name);
587
566
  let params;
588
- if (this.match(tokens_1.TokenType.LPAREN)) {
567
+ if (s.match(tokens_1.TokenType.LPAREN)) {
589
568
  params = [];
590
- if (!this.checkType(tokens_1.TokenType.RPAREN)) {
591
- params.push(this.expectName());
592
- while (this.match(tokens_1.TokenType.COMMA)) {
593
- params.push(this.expectName());
569
+ if (!s.checkType(tokens_1.TokenType.RPAREN)) {
570
+ params.push(s.expectName());
571
+ while (s.match(tokens_1.TokenType.COMMA)) {
572
+ params.push(s.expectName());
594
573
  }
595
574
  }
596
- this.expect(tokens_1.TokenType.RPAREN);
575
+ s.expect(tokens_1.TokenType.RPAREN);
597
576
  }
598
- // Herencia opcional: extends Parent
599
577
  let parent;
600
- if (this.match(tokens_1.TokenType.EXTENDS)) {
601
- parent = this.expectName();
578
+ if (s.match(tokens_1.TokenType.EXTENDS)) {
579
+ parent = s.expectName();
602
580
  }
603
- this.expect(tokens_1.TokenType.LBRACE);
604
- this.skipNewlines();
581
+ s.expect(tokens_1.TokenType.LBRACE);
582
+ s.skipNewlines();
605
583
  const members = [];
606
- while (!this.checkType(tokens_1.TokenType.RBRACE) && !this.isAtEnd()) {
607
- this.skipNewlines();
608
- if (this.checkType(tokens_1.TokenType.RBRACE))
584
+ while (!s.checkType(tokens_1.TokenType.RBRACE) && !s.isAtEnd()) {
585
+ s.skipNewlines();
586
+ if (s.checkType(tokens_1.TokenType.RBRACE))
609
587
  break;
610
- // Visibilidad: private/privado o public (default)
611
588
  let visibility = 'public';
612
- if (this.match(tokens_1.TokenType.PRIVATE)) {
589
+ if (s.match(tokens_1.TokenType.PRIVATE)) {
613
590
  visibility = 'private';
614
591
  }
615
592
  try {
@@ -620,70 +597,62 @@ class Parser {
620
597
  }
621
598
  catch (e) {
622
599
  const message = e instanceof Error ? e.message : 'Error de parseo en theory';
623
- this.diagnostics.push({
624
- severity: 'error',
625
- message,
626
- file: this.file,
627
- line: this.current().line,
628
- column: this.current().column,
629
- });
600
+ s.pushDiagnostic('error', message);
630
601
  this.advanceToNextStatement();
631
602
  }
632
603
  }
633
- this.expect(tokens_1.TokenType.RBRACE);
604
+ s.expect(tokens_1.TokenType.RBRACE);
634
605
  return { kind: 'theory_decl', name, params, parent, members, source: src };
635
606
  }
636
607
  // --- print "texto" | print formula ---
637
608
  parsePrintCmd() {
638
- const src = this.loc();
639
- this.expect(tokens_1.TokenType.PRINT);
640
- if (this.checkType(tokens_1.TokenType.STRING)) {
641
- const value = this.current().value;
642
- this.advance();
609
+ const s = this.state;
610
+ const src = s.loc();
611
+ s.expect(tokens_1.TokenType.PRINT);
612
+ if (s.checkType(tokens_1.TokenType.STRING)) {
613
+ const value = s.current().value;
614
+ s.advance();
643
615
  return { kind: 'print_cmd', value, source: src };
644
616
  }
645
- // Imprimir resultado de fórmula
646
617
  const formula = this.parseFormula();
647
618
  return { kind: 'print_cmd', value: null, formula, source: src };
648
619
  }
649
620
  // --- set x = formula ---
650
621
  parseSetCmd() {
651
- const src = this.loc();
652
- this.expect(tokens_1.TokenType.SET);
653
- const name = this.expectName();
654
- this.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
622
+ const s = this.state;
623
+ const src = s.loc();
624
+ s.expect(tokens_1.TokenType.SET);
625
+ const name = s.expectName();
626
+ s.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
655
627
  const formula = this.parseFormula();
656
628
  return { kind: 'set_cmd', name, formula, source: src };
657
629
  }
658
630
  // --- if valid FORMULA { } else if satisfiable FORMULA { } else { } ---
659
631
  parseIfStmt() {
660
- const src = this.loc();
632
+ const s = this.state;
633
+ const src = s.loc();
661
634
  const branches = [];
662
635
  let elseBranch;
663
- // Primera rama: if
664
- this.expect(tokens_1.TokenType.IF);
636
+ s.expect(tokens_1.TokenType.IF);
665
637
  branches.push(this.parseConditionBranch());
666
- // Ramas else if
667
638
  while (this.checkElseIf()) {
668
- this.expect(tokens_1.TokenType.ELSE);
669
- this.expect(tokens_1.TokenType.IF);
639
+ s.expect(tokens_1.TokenType.ELSE);
640
+ s.expect(tokens_1.TokenType.IF);
670
641
  branches.push(this.parseConditionBranch());
671
642
  }
672
- // Rama else
673
- if (this.match(tokens_1.TokenType.ELSE)) {
643
+ if (s.match(tokens_1.TokenType.ELSE)) {
674
644
  elseBranch = this.parseBlock();
675
645
  }
676
646
  return { kind: 'if_stmt', branches, elseBranch, source: src };
677
647
  }
678
648
  checkElseIf() {
679
- // Mira si hay else seguido de if (con posibles newlines entre medio)
680
- if (!this.checkType(tokens_1.TokenType.ELSE))
649
+ const s = this.state;
650
+ if (!s.checkType(tokens_1.TokenType.ELSE))
681
651
  return false;
682
- // Buscar if después de else (puede haber newlines)
683
652
  let lookahead = 1;
684
- while (this.peek(lookahead) === tokens_1.TokenType.NEWLINE)
653
+ while (s.peek(lookahead) === tokens_1.TokenType.NEWLINE)
685
654
  lookahead++;
686
- return this.peek(lookahead) === tokens_1.TokenType.IF;
655
+ return s.peek(lookahead) === tokens_1.TokenType.IF;
687
656
  }
688
657
  parseConditionBranch() {
689
658
  const condition = this.parseConditionKeyword();
@@ -692,46 +661,48 @@ class Parser {
692
661
  return { condition, formula, body };
693
662
  }
694
663
  parseConditionKeyword() {
695
- if (this.match(tokens_1.TokenType.VALID))
664
+ const s = this.state;
665
+ if (s.match(tokens_1.TokenType.VALID))
696
666
  return 'valid';
697
- if (this.match(tokens_1.TokenType.SATISFIABLE))
667
+ if (s.match(tokens_1.TokenType.SATISFIABLE))
698
668
  return 'satisfiable';
699
- // Aceptar "invalid" / "unsatisfiable" como identifiers
700
- if (this.checkType(tokens_1.TokenType.IDENTIFIER)) {
701
- const v = this.current().value.toLowerCase();
669
+ if (s.checkType(tokens_1.TokenType.IDENTIFIER)) {
670
+ const v = s.current().value.toLowerCase();
702
671
  if (v === 'invalid' || v === 'invalido') {
703
- this.advance();
672
+ s.advance();
704
673
  return 'invalid';
705
674
  }
706
675
  if (v === 'unsatisfiable' || v === 'insatisfacible') {
707
- this.advance();
676
+ s.advance();
708
677
  return 'unsatisfiable';
709
678
  }
710
679
  }
711
- throw new Error(this.contextualize(`Se esperaba una condición lógica ('valid', 'satisfiable', 'invalid' o 'unsatisfiable'), encontrado '${this.current().value}'`));
680
+ throw new Error(s.contextualize(`Se esperaba una condición lógica ('valid', 'satisfiable', 'invalid' o 'unsatisfiable'), encontrado '${s.current().value}'`));
712
681
  }
713
682
  // --- for x in {A, B, C} { body } ---
714
683
  parseForStmt() {
715
- const src = this.loc();
716
- this.expect(tokens_1.TokenType.FOR);
717
- const variable = this.expectName();
718
- this.expect(tokens_1.TokenType.IN);
719
- this.expect(tokens_1.TokenType.LBRACE);
684
+ const s = this.state;
685
+ const src = s.loc();
686
+ s.expect(tokens_1.TokenType.FOR);
687
+ const variable = s.expectName();
688
+ s.expect(tokens_1.TokenType.IN);
689
+ s.expect(tokens_1.TokenType.LBRACE);
720
690
  const items = [];
721
- if (!this.checkType(tokens_1.TokenType.RBRACE)) {
691
+ if (!s.checkType(tokens_1.TokenType.RBRACE)) {
722
692
  items.push(this.parseFormula());
723
- while (this.match(tokens_1.TokenType.COMMA)) {
693
+ while (s.match(tokens_1.TokenType.COMMA)) {
724
694
  items.push(this.parseFormula());
725
695
  }
726
696
  }
727
- this.expect(tokens_1.TokenType.RBRACE);
697
+ s.expect(tokens_1.TokenType.RBRACE);
728
698
  const body = this.parseBlock();
729
699
  return { kind: 'for_stmt', variable, items, body, source: src };
730
700
  }
731
701
  // --- while valid FORMULA { body } ---
732
702
  parseWhileStmt() {
733
- const src = this.loc();
734
- this.expect(tokens_1.TokenType.WHILE);
703
+ const s = this.state;
704
+ const src = s.loc();
705
+ s.expect(tokens_1.TokenType.WHILE);
735
706
  const condition = this.parseConditionKeyword();
736
707
  const formula = this.parseFormula();
737
708
  const body = this.parseBlock();
@@ -739,44 +710,45 @@ class Parser {
739
710
  }
740
711
  // --- fn nombre(param1, param2) { body } ---
741
712
  parseFnDecl() {
742
- const src = this.loc();
743
- this.expect(tokens_1.TokenType.FN);
744
- const name = this.expectName();
745
- this.knownFunctionNames.add(name);
746
- this.expect(tokens_1.TokenType.LPAREN);
713
+ const s = this.state;
714
+ const src = s.loc();
715
+ s.expect(tokens_1.TokenType.FN);
716
+ const name = s.expectName();
717
+ s.knownFunctionNames.add(name);
718
+ s.expect(tokens_1.TokenType.LPAREN);
747
719
  const params = [];
748
- if (!this.checkType(tokens_1.TokenType.RPAREN)) {
749
- params.push(this.expectName());
750
- while (this.match(tokens_1.TokenType.COMMA)) {
751
- params.push(this.expectName());
720
+ if (!s.checkType(tokens_1.TokenType.RPAREN)) {
721
+ params.push(s.expectName());
722
+ while (s.match(tokens_1.TokenType.COMMA)) {
723
+ params.push(s.expectName());
752
724
  }
753
725
  }
754
- this.expect(tokens_1.TokenType.RPAREN);
726
+ s.expect(tokens_1.TokenType.RPAREN);
755
727
  const body = this.parseBlock();
756
728
  return { kind: 'fn_decl', name, params, body, source: src };
757
729
  }
758
730
  // --- return formula ---
759
731
  parseReturnStmt() {
760
- const src = this.loc();
761
- this.expect(tokens_1.TokenType.RETURN);
732
+ const s = this.state;
733
+ const src = s.loc();
734
+ s.expect(tokens_1.TokenType.RETURN);
762
735
  let formula;
763
- // Si hay algo después del return que no sea newline/EOF/}
764
- if (!this.checkType(tokens_1.TokenType.NEWLINE) &&
765
- !this.checkType(tokens_1.TokenType.EOF) &&
766
- !this.checkType(tokens_1.TokenType.RBRACE)) {
736
+ if (!s.checkType(tokens_1.TokenType.NEWLINE) &&
737
+ !s.checkType(tokens_1.TokenType.EOF) &&
738
+ !s.checkType(tokens_1.TokenType.RBRACE)) {
767
739
  formula = this.parseFormula();
768
740
  }
769
741
  return { kind: 'return_stmt', formula, source: src };
770
742
  }
771
743
  // --- export STATEMENT ---
772
744
  parseExportDecl() {
773
- const src = this.loc();
774
- this.expect(tokens_1.TokenType.EXPORT);
745
+ const s = this.state;
746
+ const src = s.loc();
747
+ s.expect(tokens_1.TokenType.EXPORT);
775
748
  const stmt = this.parseStatement();
776
749
  if (!stmt) {
777
750
  throw new Error('Se esperaba un statement después de "export"');
778
751
  }
779
- // Solo permitimos exportar declaraciones
780
752
  const exportable = [
781
753
  'let_decl',
782
754
  'axiom_decl',
@@ -792,157 +764,160 @@ class Parser {
792
764
  }
793
765
  // --- define NAME(params?) := FORMULA (description "text")? ---
794
766
  parseDefineDecl() {
795
- const src = this.loc();
796
- this.expect(tokens_1.TokenType.DEFINE);
797
- const name = this.expectName();
798
- // Parámetros opcionales: define F(x, y) := ...
767
+ const s = this.state;
768
+ const src = s.loc();
769
+ s.expect(tokens_1.TokenType.DEFINE);
770
+ const name = s.expectName();
799
771
  let params;
800
- if (this.match(tokens_1.TokenType.LPAREN)) {
772
+ if (s.match(tokens_1.TokenType.LPAREN)) {
801
773
  params = [];
802
- if (!this.checkType(tokens_1.TokenType.RPAREN)) {
803
- params.push(this.expectName());
804
- while (this.match(tokens_1.TokenType.COMMA)) {
805
- params.push(this.expectName());
774
+ if (!s.checkType(tokens_1.TokenType.RPAREN)) {
775
+ params.push(s.expectName());
776
+ while (s.match(tokens_1.TokenType.COMMA)) {
777
+ params.push(s.expectName());
806
778
  }
807
779
  }
808
- this.expect(tokens_1.TokenType.RPAREN);
780
+ s.expect(tokens_1.TokenType.RPAREN);
809
781
  }
810
- // := (colon + equals) or just =
811
- if (this.match(tokens_1.TokenType.COLON)) {
812
- this.expect(tokens_1.TokenType.EQUALS);
782
+ if (s.match(tokens_1.TokenType.COLON)) {
783
+ s.expect(tokens_1.TokenType.EQUALS);
813
784
  }
814
785
  else {
815
- this.expect(tokens_1.TokenType.EQUALS);
786
+ s.expect(tokens_1.TokenType.EQUALS);
816
787
  }
817
788
  const body = this.parseFormula();
818
- // Optional description: description "text" (on next line or same line)
819
789
  let description;
820
- this.skipNewlines();
821
- if (this.checkType(tokens_1.TokenType.DESCRIPTION)) {
822
- this.advance();
823
- if (this.checkType(tokens_1.TokenType.STRING)) {
824
- description = this.current().value;
825
- this.advance();
790
+ s.skipNewlines();
791
+ if (s.checkType(tokens_1.TokenType.DESCRIPTION)) {
792
+ s.advance();
793
+ if (s.checkType(tokens_1.TokenType.STRING)) {
794
+ description = s.current().value;
795
+ s.advance();
826
796
  }
827
797
  }
828
798
  return { kind: 'define_decl', name, params, body, description, source: src };
829
799
  }
830
800
  // --- unfold FORMULA ---
831
801
  parseUnfoldCmd() {
832
- const src = this.loc();
833
- this.expect(tokens_1.TokenType.UNFOLD);
802
+ const s = this.state;
803
+ const src = s.loc();
804
+ s.expect(tokens_1.TokenType.UNFOLD);
834
805
  const formula = this.parseFormula();
835
806
  return { kind: 'unfold_cmd', formula, source: src };
836
807
  }
837
808
  // --- fold FORMULA ---
838
809
  parseFoldCmd() {
839
- const src = this.loc();
840
- this.expect(tokens_1.TokenType.FOLD);
810
+ const s = this.state;
811
+ const src = s.loc();
812
+ s.expect(tokens_1.TokenType.FOLD);
841
813
  const formula = this.parseFormula();
842
814
  return { kind: 'fold_cmd', formula, source: src };
843
815
  }
844
816
  // --- source NAME { key "value", ... } ---
845
817
  parseSourceDecl() {
846
- const src = this.loc();
847
- this.expect(tokens_1.TokenType.SOURCE_KW);
848
- const name = this.expectName();
849
- this.expect(tokens_1.TokenType.LBRACE);
850
- this.skipNewlines();
818
+ const s = this.state;
819
+ const src = s.loc();
820
+ s.expect(tokens_1.TokenType.SOURCE_KW);
821
+ const name = s.expectName();
822
+ s.expect(tokens_1.TokenType.LBRACE);
823
+ s.skipNewlines();
851
824
  const fields = [];
852
- while (!this.checkType(tokens_1.TokenType.RBRACE) && !this.isAtEnd()) {
853
- this.skipNewlines();
854
- if (this.checkType(tokens_1.TokenType.RBRACE))
825
+ while (!s.checkType(tokens_1.TokenType.RBRACE) && !s.isAtEnd()) {
826
+ s.skipNewlines();
827
+ if (s.checkType(tokens_1.TokenType.RBRACE))
855
828
  break;
856
- const key = this.expectName();
857
- // Value: string or number
858
- if (this.checkType(tokens_1.TokenType.STRING)) {
859
- fields.push({ key, value: this.current().value });
860
- this.advance();
829
+ const key = s.expectName();
830
+ if (s.checkType(tokens_1.TokenType.STRING)) {
831
+ fields.push({ key, value: s.current().value });
832
+ s.advance();
861
833
  }
862
- else if (this.checkType(tokens_1.TokenType.NUMBER)) {
863
- fields.push({ key, value: parseFloat(this.current().value) });
864
- this.advance();
834
+ else if (s.checkType(tokens_1.TokenType.NUMBER)) {
835
+ fields.push({ key, value: parseFloat(s.current().value) });
836
+ s.advance();
865
837
  }
866
- else if (this.checkType(tokens_1.TokenType.MINUS)) {
867
- // Negative number (e.g., year -350)
868
- this.advance();
869
- if (this.checkType(tokens_1.TokenType.NUMBER)) {
870
- fields.push({ key, value: -parseFloat(this.current().value) });
871
- this.advance();
838
+ else if (s.checkType(tokens_1.TokenType.MINUS)) {
839
+ s.advance();
840
+ if (s.checkType(tokens_1.TokenType.NUMBER)) {
841
+ fields.push({ key, value: -parseFloat(s.current().value) });
842
+ s.advance();
872
843
  }
873
844
  }
874
- this.skipNewlines();
845
+ s.skipNewlines();
875
846
  }
876
- this.expect(tokens_1.TokenType.RBRACE);
847
+ s.expect(tokens_1.TokenType.RBRACE);
877
848
  return { kind: 'source_decl', name, fields, source: src };
878
849
  }
879
850
  // --- interpret "text" as FORMULA | interpret IDENT as FORMULA ---
880
851
  parseInterpretCmd() {
881
- const src = this.loc();
882
- this.expect(tokens_1.TokenType.INTERPRET);
852
+ const s = this.state;
853
+ const src = s.loc();
854
+ s.expect(tokens_1.TokenType.INTERPRET);
883
855
  let text;
884
856
  let passageRef;
885
- if (this.checkType(tokens_1.TokenType.STRING)) {
886
- text = this.current().value;
887
- this.advance();
857
+ if (s.checkType(tokens_1.TokenType.STRING)) {
858
+ text = s.current().value;
859
+ s.advance();
888
860
  }
889
861
  else {
890
- // interpret passageRef as FORMULA
891
- passageRef = this.expectName();
862
+ passageRef = s.expectName();
892
863
  text = passageRef;
893
864
  }
894
- this.expect(tokens_1.TokenType.AS);
865
+ s.expect(tokens_1.TokenType.AS);
895
866
  const formula = this.parseFormula();
896
867
  return { kind: 'interpret_cmd', text, passageRef, formula, source: src };
897
868
  }
898
869
  // --- glossary ---
899
870
  parseGlossaryCmd() {
900
- const src = this.loc();
901
- this.expect(tokens_1.TokenType.GLOSSARY);
871
+ const s = this.state;
872
+ const src = s.loc();
873
+ s.expect(tokens_1.TokenType.GLOSSARY);
902
874
  return { kind: 'glossary_cmd', source: src };
903
875
  }
904
876
  // --- nombre(arg1, arg2) — llamada a función ---
905
877
  parseFnCall() {
906
- const src = this.loc();
907
- const name = this.expectName();
908
- this.expect(tokens_1.TokenType.LPAREN);
878
+ const s = this.state;
879
+ const src = s.loc();
880
+ const name = s.expectName();
881
+ s.expect(tokens_1.TokenType.LPAREN);
909
882
  const args = [];
910
- if (!this.checkType(tokens_1.TokenType.RPAREN)) {
883
+ if (!s.checkType(tokens_1.TokenType.RPAREN)) {
911
884
  args.push(this.parseFormula());
912
- while (this.match(tokens_1.TokenType.COMMA)) {
885
+ while (s.match(tokens_1.TokenType.COMMA)) {
913
886
  args.push(this.parseFormula());
914
887
  }
915
888
  }
916
- this.expect(tokens_1.TokenType.RPAREN);
889
+ s.expect(tokens_1.TokenType.RPAREN);
917
890
  return { kind: 'fn_call', name, args, source: src };
918
891
  }
919
892
  // --- obj.method(arg1, arg2) ---
920
893
  parseMemberFnCall() {
921
- const src = this.loc();
922
- const obj = this.expectIdent();
923
- this.expect(tokens_1.TokenType.DOT);
924
- const method = this.expectIdent();
894
+ const s = this.state;
895
+ const src = s.loc();
896
+ const obj = s.expectIdent();
897
+ s.expect(tokens_1.TokenType.DOT);
898
+ const method = s.expectIdent();
925
899
  const fullName = `${obj}.${method}`;
926
- this.expect(tokens_1.TokenType.LPAREN);
900
+ s.expect(tokens_1.TokenType.LPAREN);
927
901
  const args = [];
928
- if (!this.checkType(tokens_1.TokenType.RPAREN)) {
902
+ if (!s.checkType(tokens_1.TokenType.RPAREN)) {
929
903
  args.push(this.parseFormula());
930
- while (this.match(tokens_1.TokenType.COMMA)) {
904
+ while (s.match(tokens_1.TokenType.COMMA)) {
931
905
  args.push(this.parseFormula());
932
906
  }
933
907
  }
934
- this.expect(tokens_1.TokenType.RPAREN);
908
+ s.expect(tokens_1.TokenType.RPAREN);
935
909
  return { kind: 'fn_call', name: fullName, args, source: src };
936
910
  }
937
911
  // --- Helper: parsear un bloque { statements } ---
938
912
  parseBlock() {
939
- this.skipNewlines();
940
- this.expect(tokens_1.TokenType.LBRACE);
941
- this.skipNewlines();
913
+ const s = this.state;
914
+ s.skipNewlines();
915
+ s.expect(tokens_1.TokenType.LBRACE);
916
+ s.skipNewlines();
942
917
  const body = [];
943
- while (!this.checkType(tokens_1.TokenType.RBRACE) && !this.isAtEnd()) {
944
- this.skipNewlines();
945
- if (this.checkType(tokens_1.TokenType.RBRACE))
918
+ while (!s.checkType(tokens_1.TokenType.RBRACE) && !s.isAtEnd()) {
919
+ s.skipNewlines();
920
+ if (s.checkType(tokens_1.TokenType.RBRACE))
946
921
  break;
947
922
  try {
948
923
  const stmt = this.parseStatement();
@@ -951,611 +926,18 @@ class Parser {
951
926
  }
952
927
  catch (e) {
953
928
  const message = e instanceof Error ? e.message : 'Error de parseo en bloque';
954
- this.diagnostics.push({
955
- severity: 'error',
956
- message,
957
- file: this.file,
958
- line: this.current().line,
959
- column: this.current().column,
960
- });
929
+ s.pushDiagnostic('error', message);
961
930
  this.advanceToNextStatement();
962
931
  }
963
932
  }
964
- this.expect(tokens_1.TokenType.RBRACE);
933
+ s.expect(tokens_1.TokenType.RBRACE);
965
934
  return body;
966
935
  }
967
- // --- Parsing de fórmulas (precedencia) ---
968
- // Precedencia (de menor a mayor):
969
- // 1. <-> (bicondicional)
970
- // 2. -> (implicación, asocia a la derecha)
971
- // 3. | (disyunción)
972
- // 4. & (conjunción)
973
- // 5. ! (negación) y átomos
936
+ // --- Delegacion a modulo de formulas ---
974
937
  parseFormula() {
975
- return this.parseBiconditional();
976
- }
977
- parseBiconditional() {
978
- let left = this.parseImplication();
979
- while (this.match(tokens_1.TokenType.BICONDITIONAL)) {
980
- const right = this.parseImplication();
981
- left = { kind: 'biconditional', args: [left, right], source: this.loc() };
982
- }
983
- return left;
984
- }
985
- parseImplication() {
986
- const left = this.parseDisjunction();
987
- if (this.match(tokens_1.TokenType.ARROW)) {
988
- // Asociatividad a la derecha
989
- const right = this.parseImplication();
990
- return { kind: 'implies', args: [left, right], source: this.loc() };
991
- }
992
- return left;
993
- }
994
- parseDisjunction() {
995
- let left = this.parseUntil();
996
- let firstKind = null;
997
- while (this.match(tokens_1.TokenType.OR) || this.match(tokens_1.TokenType.XOR) || this.match(tokens_1.TokenType.NOR)) {
998
- const type = this.previous().type;
999
- const currentKind = type === tokens_1.TokenType.OR ? 'or' : type === tokens_1.TokenType.XOR ? 'xor' : 'nor';
1000
- if (firstKind !== null && firstKind !== currentKind) {
1001
- const tok = this.previous();
1002
- this.diagnostics.push({
1003
- severity: 'warning',
1004
- message: `Mezcla de conectivos ${firstKind}/${currentKind} al mismo nivel de precedencia; asociación izquierda aplicada — usar paréntesis para desambiguar`,
1005
- file: this.file,
1006
- line: tok.line,
1007
- column: tok.column,
1008
- });
1009
- }
1010
- firstKind = firstKind ?? currentKind;
1011
- const right = this.parseUntil();
1012
- left = { kind: currentKind, args: [left, right], source: this.loc() };
1013
- }
1014
- return left;
1015
- }
1016
- parseUntil() {
1017
- let left = this.parseConjunction();
1018
- while (this.match(tokens_1.TokenType.UNTIL)) {
1019
- const right = this.parseConjunction();
1020
- left = { kind: 'temporal_until', args: [left, right], source: this.loc() };
1021
- }
1022
- return left;
1023
- }
1024
- parseConjunction() {
1025
- let left = this.parseComparison();
1026
- let firstKind = null;
1027
- while (this.match(tokens_1.TokenType.AND) || this.match(tokens_1.TokenType.NAND)) {
1028
- const type = this.previous().type;
1029
- const currentKind = type === tokens_1.TokenType.AND ? 'and' : 'nand';
1030
- if (firstKind !== null && firstKind !== currentKind) {
1031
- const tok = this.previous();
1032
- this.diagnostics.push({
1033
- severity: 'warning',
1034
- message: `Mezcla de conectivos ${firstKind}/${currentKind} al mismo nivel de precedencia; asociación izquierda aplicada — usar paréntesis para desambiguar`,
1035
- file: this.file,
1036
- line: tok.line,
1037
- column: tok.column,
1038
- });
1039
- }
1040
- firstKind = firstKind ?? currentKind;
1041
- const right = this.parseComparison();
1042
- left = { kind: currentKind, args: [left, right], source: this.loc() };
1043
- }
1044
- return left;
1045
- }
1046
- // --- Arithmetic precedence ---
1047
- parseComparison() {
1048
- let left = this.parseAdditive();
1049
- while (this.checkType(tokens_1.TokenType.LT) ||
1050
- this.checkType(tokens_1.TokenType.GT) ||
1051
- this.checkType(tokens_1.TokenType.LTE) ||
1052
- this.checkType(tokens_1.TokenType.GTE)) {
1053
- if (this.match(tokens_1.TokenType.LT)) {
1054
- const right = this.parseAdditive();
1055
- left = { kind: 'less', args: [left, right], source: this.loc() };
1056
- }
1057
- else if (this.match(tokens_1.TokenType.GT)) {
1058
- const right = this.parseAdditive();
1059
- left = { kind: 'greater', args: [left, right], source: this.loc() };
1060
- }
1061
- else if (this.match(tokens_1.TokenType.LTE)) {
1062
- const right = this.parseAdditive();
1063
- left = { kind: 'less_eq', args: [left, right], source: this.loc() };
1064
- }
1065
- else if (this.match(tokens_1.TokenType.GTE)) {
1066
- const right = this.parseAdditive();
1067
- left = { kind: 'greater_eq', args: [left, right], source: this.loc() };
1068
- }
1069
- }
1070
- return left;
1071
- }
1072
- parseAdditive() {
1073
- let left = this.parseMultiplicative();
1074
- while (this.checkType(tokens_1.TokenType.PLUS) || this.checkType(tokens_1.TokenType.MINUS)) {
1075
- if (this.match(tokens_1.TokenType.PLUS)) {
1076
- const right = this.parseMultiplicative();
1077
- left = { kind: 'add', args: [left, right], source: this.loc() };
1078
- }
1079
- else if (this.match(tokens_1.TokenType.MINUS)) {
1080
- const right = this.parseMultiplicative();
1081
- left = { kind: 'subtract', args: [left, right], source: this.loc() };
1082
- }
1083
- }
1084
- return left;
1085
- }
1086
- parseMultiplicative() {
1087
- let left = this.parseUnary();
1088
- while (this.checkType(tokens_1.TokenType.STAR) ||
1089
- this.checkType(tokens_1.TokenType.SLASH) ||
1090
- this.checkType(tokens_1.TokenType.PERCENT)) {
1091
- if (this.match(tokens_1.TokenType.STAR)) {
1092
- const right = this.parseUnary();
1093
- left = { kind: 'multiply', args: [left, right], source: this.loc() };
1094
- }
1095
- else if (this.match(tokens_1.TokenType.SLASH)) {
1096
- const right = this.parseUnary();
1097
- left = { kind: 'divide', args: [left, right], source: this.loc() };
1098
- }
1099
- else if (this.match(tokens_1.TokenType.PERCENT)) {
1100
- const right = this.parseUnary();
1101
- left = { kind: 'modulo', args: [left, right], source: this.loc() };
1102
- }
1103
- }
1104
- return left;
1105
- }
1106
- parseUnary() {
1107
- // Unary minus: -expr → subtract(0, expr)
1108
- if (this.match(tokens_1.TokenType.MINUS)) {
1109
- const operand = this.parseUnary();
1110
- return {
1111
- kind: 'subtract',
1112
- args: [{ kind: 'number', value: 0, source: this.loc() }, operand],
1113
- source: this.loc(),
1114
- };
1115
- }
1116
- if (this.match(tokens_1.TokenType.NOT)) {
1117
- const operand = this.parseUnary();
1118
- return { kind: 'not', args: [operand], source: this.loc() };
1119
- }
1120
- if (this.match(tokens_1.TokenType.BOX)) {
1121
- const operand = this.parseUnary();
1122
- return { kind: 'modal_necessity', args: [operand], source: this.loc() };
1123
- }
1124
- if (this.match(tokens_1.TokenType.DIAMOND)) {
1125
- const operand = this.parseUnary();
1126
- return { kind: 'modal_possibility', args: [operand], source: this.loc() };
1127
- }
1128
- if (this.match(tokens_1.TokenType.FORALL)) {
1129
- const variable = this.expectIdent();
1130
- const operand = this.parseUnary();
1131
- return { kind: 'forall', variable, args: [operand], source: this.loc() };
1132
- }
1133
- if (this.match(tokens_1.TokenType.EXISTS)) {
1134
- const variable = this.expectIdent();
1135
- const operand = this.parseUnary();
1136
- return { kind: 'exists', variable, args: [operand], source: this.loc() };
1137
- }
1138
- if (this.match(tokens_1.TokenType.NEXT)) {
1139
- const operand = this.parseUnary();
1140
- return { kind: 'temporal_next', args: [operand], source: this.loc() };
1141
- }
1142
- return this.parsePostfix();
1143
- }
1144
- parsePostfix() {
1145
- let expr = this.parsePrimary();
1146
- while (this.match(tokens_1.TokenType.LBRACKET)) {
1147
- const index = this.parseFormula();
1148
- this.expect(tokens_1.TokenType.RBRACKET);
1149
- expr = {
1150
- kind: 'fn_call',
1151
- name: 'at',
1152
- args: [expr, index],
1153
- source: expr.source ?? index.source ?? this.loc(),
1154
- };
1155
- }
1156
- return expr;
1157
- }
1158
- parsePrimary() {
1159
- // Constantes lógicas ⊤/⊥ (true/false/verdadero/falso)
1160
- if (this.checkType(tokens_1.TokenType.TRUE_CONST)) {
1161
- const tok = this.current();
1162
- this.advance();
1163
- return { kind: 'true', source: { line: tok.line, column: tok.column } };
1164
- }
1165
- if (this.checkType(tokens_1.TokenType.FALSE_CONST)) {
1166
- const tok = this.current();
1167
- this.advance();
1168
- return { kind: 'false', source: { line: tok.line, column: tok.column } };
1169
- }
1170
- // Literal numérico
1171
- if (this.checkType(tokens_1.TokenType.NUMBER)) {
1172
- const tok = this.current();
1173
- this.advance();
1174
- return {
1175
- kind: 'number',
1176
- value: parseFloat(tok.value),
1177
- source: { line: tok.line, column: tok.column },
1178
- };
1179
- }
1180
- if (this.match(tokens_1.TokenType.LBRACKET)) {
1181
- const items = [];
1182
- if (!this.checkType(tokens_1.TokenType.RBRACKET)) {
1183
- items.push(this.parseFormula());
1184
- while (this.match(tokens_1.TokenType.COMMA)) {
1185
- items.push(this.parseFormula());
1186
- }
1187
- }
1188
- this.expect(tokens_1.TokenType.RBRACKET);
1189
- return {
1190
- kind: 'list',
1191
- args: items,
1192
- source: this.loc(),
1193
- };
1194
- }
1195
- // Literal de texto (String)
1196
- if (this.checkType(tokens_1.TokenType.STRING)) {
1197
- const tok = this.current();
1198
- this.advance();
1199
- // Lo representamos como un átomo especial o un nuevo kind.
1200
- // Por simplicidad para el motor lógico, lo tratamos como un átomo cuyo nombre es el valor del string entre comillas.
1201
- return {
1202
- kind: 'atom',
1203
- name: `"${tok.value}"`,
1204
- source: { line: tok.line, column: tok.column },
1205
- };
1206
- }
1207
- // Paréntesis
1208
- if (this.match(tokens_1.TokenType.LPAREN)) {
1209
- const inner = this.parseFormula();
1210
- this.expect(tokens_1.TokenType.RPAREN);
1211
- return inner;
1212
- }
1213
- // Dot notation con keyword como prefijo: Logic.mp, Theory.axiom, etc.
1214
- // Si el token actual es una keyword seguida de DOT + IDENTIFIER, tratarlo como nombre calificado
1215
- if (this.checkType(tokens_1.TokenType.DOT) === false &&
1216
- this.current().type !== tokens_1.TokenType.IDENTIFIER &&
1217
- this.current().type !== tokens_1.TokenType.NEWLINE &&
1218
- this.current().type !== tokens_1.TokenType.EOF &&
1219
- this.peek(1) === tokens_1.TokenType.DOT &&
1220
- this.peek(2) === tokens_1.TokenType.IDENTIFIER) {
1221
- const tok = this.current();
1222
- this.advance(); // consumir keyword
1223
- this.advance(); // consumir DOT
1224
- const memberTok = this.current();
1225
- this.advance(); // consumir IDENTIFIER
1226
- return {
1227
- kind: 'atom',
1228
- name: `${tok.value}.${memberTok.value}`,
1229
- source: { line: tok.line, column: tok.column },
1230
- };
1231
- }
1232
- // Predicado o Atomo proposicional
1233
- if (this.checkType(tokens_1.TokenType.IDENTIFIER)) {
1234
- const tok = this.current();
1235
- this.advance();
1236
- // Notación con punto: Theory.member (acceso calificado)
1237
- if (this.checkType(tokens_1.TokenType.DOT) && this.peek(1) === tokens_1.TokenType.IDENTIFIER) {
1238
- this.advance(); // consumir DOT
1239
- const memberTok = this.current();
1240
- this.advance(); // consumir IDENTIFIER
1241
- // Nombre calificado: "Theory.member"
1242
- return {
1243
- kind: 'atom',
1244
- name: `${tok.value}.${memberTok.value}`,
1245
- source: { line: tok.line, column: tok.column },
1246
- };
1247
- }
1248
- if (this.match(tokens_1.TokenType.LPAREN)) {
1249
- // Modal alias check: e.g. K(P) in epistemic, O(P) in deontic
1250
- const profileAliases = MODAL_ALIASES[this.currentProfile];
1251
- const aliasType = profileAliases?.[tok.value];
1252
- if (aliasType) {
1253
- const inner = this.parseFormula();
1254
- this.expect(tokens_1.TokenType.RPAREN);
1255
- if (aliasType === 'box') {
1256
- return {
1257
- kind: 'modal_necessity',
1258
- args: [inner],
1259
- source: { line: tok.line, column: tok.column },
1260
- };
1261
- }
1262
- else if (aliasType === 'diamond') {
1263
- return {
1264
- kind: 'modal_possibility',
1265
- args: [inner],
1266
- source: { line: tok.line, column: tok.column },
1267
- };
1268
- }
1269
- else {
1270
- // box_not: e.g. deontic F(φ) = □(¬φ)
1271
- return {
1272
- kind: 'modal_necessity',
1273
- args: [
1274
- { kind: 'not', args: [inner], source: { line: tok.line, column: tok.column } },
1275
- ],
1276
- source: { line: tok.line, column: tok.column },
1277
- };
1278
- }
1279
- }
1280
- // Podría ser un predicado P(x, y) o una llamada a función fn(arg1, arg2)
1281
- if (this.knownFunctionNames.has(tok.value) || this.knownTheoryNames.has(tok.value)) {
1282
- const args = [];
1283
- if (!this.checkType(tokens_1.TokenType.RPAREN)) {
1284
- args.push(this.parseFormula());
1285
- while (this.match(tokens_1.TokenType.COMMA)) {
1286
- args.push(this.parseFormula());
1287
- }
1288
- }
1289
- this.expect(tokens_1.TokenType.RPAREN);
1290
- return {
1291
- kind: 'fn_call',
1292
- name: tok.value,
1293
- args,
1294
- source: { line: tok.line, column: tok.column },
1295
- };
1296
- }
1297
- // Predicado: P(x, y, ...)
1298
- const args = [];
1299
- if (!this.checkType(tokens_1.TokenType.RPAREN)) {
1300
- args.push(this.parseFormula());
1301
- while (this.match(tokens_1.TokenType.COMMA)) {
1302
- args.push(this.parseFormula());
1303
- }
1304
- }
1305
- this.expect(tokens_1.TokenType.RPAREN);
1306
- const paramStrings = args.map((a) => this.formulaToString(a));
1307
- const predFormula = {
1308
- kind: 'predicate',
1309
- name: tok.value,
1310
- params: paramStrings,
1311
- source: { line: tok.line, column: tok.column },
1312
- };
1313
- // FOL igualdad: P(x) = Q(y) (raro pero posible)
1314
- if (this.checkType(tokens_1.TokenType.EQUALS)) {
1315
- this.advance();
1316
- const right = this.parsePrimary();
1317
- return {
1318
- kind: 'equals',
1319
- args: [predFormula, right],
1320
- source: { line: tok.line, column: tok.column },
1321
- };
1322
- }
1323
- return predFormula;
1324
- }
1325
- // FOL igualdad: x = y (identidad entre términos)
1326
- if (this.checkType(tokens_1.TokenType.EQUALS)) {
1327
- this.advance();
1328
- const rightTok = this.current();
1329
- if (this.checkType(tokens_1.TokenType.IDENTIFIER)) {
1330
- this.advance();
1331
- const left = {
1332
- kind: 'atom',
1333
- name: tok.value,
1334
- source: { line: tok.line, column: tok.column },
1335
- };
1336
- const right = {
1337
- kind: 'atom',
1338
- name: rightTok.value,
1339
- source: { line: rightTok.line, column: rightTok.column },
1340
- };
1341
- return {
1342
- kind: 'equals',
1343
- args: [left, right],
1344
- source: { line: tok.line, column: tok.column },
1345
- };
1346
- }
1347
- // Si no es un identificador, backtrack — el = pertenece al statement
1348
- this.pos--;
1349
- }
1350
- return { kind: 'atom', name: tok.value, source: { line: tok.line, column: tok.column } };
1351
- }
1352
- throw new Error(`Se esperaba formula en linea ${this.current().line}, columna ${this.current().column}, ` +
1353
- `encontrado: '${this.current().value}' (${this.current().type})`);
1354
- }
1355
- // --- Helpers ---
1356
- parseIdList() {
1357
- this.expect(tokens_1.TokenType.LBRACE);
1358
- const ids = [];
1359
- if (!this.checkType(tokens_1.TokenType.RBRACE)) {
1360
- ids.push(this.expectIdent());
1361
- while (this.match(tokens_1.TokenType.COMMA)) {
1362
- ids.push(this.expectIdent());
1363
- }
1364
- }
1365
- this.expect(tokens_1.TokenType.RBRACE);
1366
- return ids;
1367
- }
1368
- collectAssociativeArgs(f, kind) {
1369
- if (f.kind !== kind || !f.args?.length)
1370
- return [f];
1371
- const items = [];
1372
- for (const arg of f.args) {
1373
- if (!arg)
1374
- continue;
1375
- items.push(...this.collectAssociativeArgs(arg, kind));
1376
- }
1377
- return items;
1378
- }
1379
- formulaToString(f) {
1380
- const arg0 = f.args?.[0];
1381
- const arg1 = f.args?.[1];
1382
- switch (f.kind) {
1383
- case 'atom':
1384
- return f.name || '?';
1385
- case 'list':
1386
- return `[${(f.args ?? []).map((a) => this.formulaToString(a)).join(', ')}]`;
1387
- case 'number':
1388
- return f.value !== undefined ? String(f.value) : '?';
1389
- case 'not':
1390
- return arg0 ? `!${this.formulaToString(arg0)}` : '!?';
1391
- case 'modal_necessity':
1392
- return arg0 ? `[]${this.formulaToString(arg0)}` : '[]?';
1393
- case 'modal_possibility':
1394
- return arg0 ? `<>${this.formulaToString(arg0)}` : '<>?';
1395
- case 'forall':
1396
- return arg0
1397
- ? `forall ${f.variable} ${this.formulaToString(arg0)}`
1398
- : `forall ${f.variable} ?`;
1399
- case 'exists':
1400
- return arg0
1401
- ? `exists ${f.variable} ${this.formulaToString(arg0)}`
1402
- : `exists ${f.variable} ?`;
1403
- case 'predicate': {
1404
- const params = f.params || [];
1405
- return `${f.name || '?'}(${params.join(', ')})`;
1406
- }
1407
- case 'and':
1408
- return arg0 && arg1
1409
- ? `(${this.collectAssociativeArgs(f, 'and')
1410
- .map((a) => this.formulaToString(a))
1411
- .join(' & ')})`
1412
- : '(? & ?)';
1413
- case 'or':
1414
- return arg0 && arg1
1415
- ? `(${this.collectAssociativeArgs(f, 'or')
1416
- .map((a) => this.formulaToString(a))
1417
- .join(' | ')})`
1418
- : '(? | ?)';
1419
- case 'nand':
1420
- return arg0 && arg1
1421
- ? `(${this.formulaToString(arg0)} ↑ ${this.formulaToString(arg1)})`
1422
- : '(? ↑ ?)';
1423
- case 'nor':
1424
- return arg0 && arg1
1425
- ? `(${this.formulaToString(arg0)} ↓ ${this.formulaToString(arg1)})`
1426
- : '(? ↓ ?)';
1427
- case 'xor':
1428
- return arg0 && arg1
1429
- ? `(${this.collectAssociativeArgs(f, 'xor')
1430
- .map((a) => this.formulaToString(a))
1431
- .join(' ⊕ ')})`
1432
- : '(? ⊕ ?)';
1433
- case 'implies':
1434
- return arg0 && arg1
1435
- ? `(${this.formulaToString(arg0)} -> ${this.formulaToString(arg1)})`
1436
- : '(? -> ?)';
1437
- case 'biconditional':
1438
- return arg0 && arg1
1439
- ? `(${this.formulaToString(arg0)} <-> ${this.formulaToString(arg1)})`
1440
- : '(? <-> ?)';
1441
- case 'equals':
1442
- return arg0 && arg1
1443
- ? `(${this.formulaToString(arg0)} = ${this.formulaToString(arg1)})`
1444
- : '(? = ?)';
1445
- case 'temporal_next':
1446
- return arg0 ? `X(${this.formulaToString(arg0)})` : 'X(?)';
1447
- case 'temporal_until':
1448
- return arg0 && arg1
1449
- ? `(${this.formulaToString(arg0)} U ${this.formulaToString(arg1)})`
1450
- : '(? U ?)';
1451
- case 'fn_call':
1452
- return `${f.name || '?'}(${(f.args ?? []).map((a) => this.formulaToString(a)).join(', ')})`;
1453
- default:
1454
- return '?';
1455
- }
1456
- }
1457
- current() {
1458
- if (this.pos >= this.tokens.length) {
1459
- return { type: tokens_1.TokenType.EOF, value: '', line: 0, column: 0 };
1460
- }
1461
- return this.tokens[this.pos];
1462
- }
1463
- previous() {
1464
- if (this.pos === 0)
1465
- return this.tokens[0];
1466
- return this.tokens[this.pos - 1];
1467
- }
1468
- peek(offset) {
1469
- const idx = this.pos + offset;
1470
- if (idx >= this.tokens.length)
1471
- return tokens_1.TokenType.EOF;
1472
- return this.tokens[idx].type;
1473
- }
1474
- advance() {
1475
- const tok = this.current();
1476
- this.pos++;
1477
- return tok;
1478
- }
1479
- isAtEnd() {
1480
- return this.current().type === tokens_1.TokenType.EOF;
1481
- }
1482
- checkType(type) {
1483
- return this.current().type === type;
1484
- }
1485
- match(type) {
1486
- if (this.checkType(type)) {
1487
- this.advance();
1488
- return true;
1489
- }
1490
- return false;
1491
- }
1492
- expect(type) {
1493
- if (this.checkType(type)) {
1494
- return this.advance();
1495
- }
1496
- throw new Error(this.contextualize(`Se esperaba ${type}, encontrado '${this.current().value}' (${this.current().type}) ` +
1497
- `en linea ${this.current().line}, columna ${this.current().column}`));
1498
- }
1499
- expectOneOf(...types) {
1500
- for (const type of types) {
1501
- if (this.checkType(type)) {
1502
- return this.advance();
1503
- }
1504
- }
1505
- throw new Error(this.contextualize(`Se esperaba ${types.join(' o ')}, encontrado '${this.current().value}' (${this.current().type}) ` +
1506
- `en linea ${this.current().line}, columna ${this.current().column}`));
1507
- }
1508
- expectIdent() {
1509
- const tok = this.expect(tokens_1.TokenType.IDENTIFIER);
1510
- return tok.value;
1511
- }
1512
- /**
1513
- * Acepta un IDENTIFIER o cualquier keyword como nombre
1514
- * (para soportar nombres como "Logic", "Theory", etc. que colisionan con keywords)
1515
- */
1516
- expectName() {
1517
- const tok = this.current();
1518
- if (tok.type === tokens_1.TokenType.IDENTIFIER) {
1519
- this.advance();
1520
- return tok.value;
1521
- }
1522
- // Aceptar cualquier keyword como nombre en contextos de nombre
1523
- if (tok.type !== tokens_1.TokenType.NEWLINE &&
1524
- tok.type !== tokens_1.TokenType.EOF &&
1525
- tok.type !== tokens_1.TokenType.LPAREN &&
1526
- tok.type !== tokens_1.TokenType.RPAREN &&
1527
- tok.type !== tokens_1.TokenType.LBRACE &&
1528
- tok.type !== tokens_1.TokenType.RBRACE &&
1529
- tok.type !== tokens_1.TokenType.COLON &&
1530
- tok.type !== tokens_1.TokenType.EQUALS &&
1531
- tok.type !== tokens_1.TokenType.ARROW &&
1532
- tok.type !== tokens_1.TokenType.AND &&
1533
- tok.type !== tokens_1.TokenType.OR &&
1534
- tok.type !== tokens_1.TokenType.NOT &&
1535
- tok.type !== tokens_1.TokenType.DOT &&
1536
- tok.type !== tokens_1.TokenType.COMMA &&
1537
- tok.type !== tokens_1.TokenType.STRING &&
1538
- tok.type !== tokens_1.TokenType.NUMBER) {
1539
- this.advance();
1540
- return tok.value;
1541
- }
1542
- throw new Error(this.contextualize(`Se esperaba nombre/identificador, encontrado '${tok.value}' (${tok.type}) ` +
1543
- `en linea ${tok.line}, columna ${tok.column}`));
1544
- }
1545
- contextualize(message) {
1546
- if (this.contextStack.length === 0)
1547
- return message;
1548
- return `${message} mientras se parseaba ${this.contextStack.join(' > ')}`;
1549
- }
1550
- withContext(context, fn) {
1551
- this.contextStack.push(context);
1552
- try {
1553
- return fn();
1554
- }
1555
- finally {
1556
- this.contextStack.pop();
1557
- }
938
+ return (0, formulas_1.parseFormula)(this.state);
1558
939
  }
940
+ // --- Helpers de diagnostico/descripcion ---
1559
941
  describeStatementContext(tok) {
1560
942
  switch (tok.type) {
1561
943
  case tokens_1.TokenType.LOGIC:
@@ -1629,17 +1011,8 @@ class Parser {
1629
1011
  return `statement '${tok.value}'`;
1630
1012
  }
1631
1013
  }
1632
- loc() {
1633
- const tok = this.current();
1634
- return { line: tok.line, column: tok.column, file: this.file };
1635
- }
1636
- skipNewlines() {
1637
- while (this.checkType(tokens_1.TokenType.NEWLINE)) {
1638
- this.advance();
1639
- }
1640
- }
1641
1014
  advanceToNextStatement() {
1642
- // Avanza hasta encontrar un newline o un token que inicie un statement
1015
+ const s = this.state;
1643
1016
  const statementStarters = new Set([
1644
1017
  tokens_1.TokenType.LOGIC,
1645
1018
  tokens_1.TokenType.AXIOM,
@@ -1682,35 +1055,35 @@ class Parser {
1682
1055
  let parenDepth = 0;
1683
1056
  let braceDepth = 0;
1684
1057
  let bracketDepth = 0;
1685
- while (!this.isAtEnd()) {
1686
- if (this.checkType(tokens_1.TokenType.NEWLINE) &&
1058
+ while (!s.isAtEnd()) {
1059
+ if (s.checkType(tokens_1.TokenType.NEWLINE) &&
1687
1060
  parenDepth === 0 &&
1688
1061
  braceDepth === 0 &&
1689
1062
  bracketDepth === 0) {
1690
- this.skipNewlines();
1063
+ s.skipNewlines();
1691
1064
  return;
1692
1065
  }
1693
1066
  if (parenDepth === 0 &&
1694
1067
  braceDepth === 0 &&
1695
1068
  bracketDepth === 0 &&
1696
- statementStarters.has(this.current().type)) {
1697
- return; // Encontramos el inicio del siguiente statement
1069
+ statementStarters.has(s.current().type)) {
1070
+ return;
1698
1071
  }
1699
- if (this.checkType(tokens_1.TokenType.LPAREN))
1072
+ if (s.checkType(tokens_1.TokenType.LPAREN))
1700
1073
  parenDepth += 1;
1701
- else if (this.checkType(tokens_1.TokenType.RPAREN))
1074
+ else if (s.checkType(tokens_1.TokenType.RPAREN))
1702
1075
  parenDepth = Math.max(0, parenDepth - 1);
1703
- else if (this.checkType(tokens_1.TokenType.LBRACE))
1076
+ else if (s.checkType(tokens_1.TokenType.LBRACE))
1704
1077
  braceDepth += 1;
1705
- else if (this.checkType(tokens_1.TokenType.RBRACE))
1078
+ else if (s.checkType(tokens_1.TokenType.RBRACE))
1706
1079
  braceDepth = Math.max(0, braceDepth - 1);
1707
- else if (this.checkType(tokens_1.TokenType.LBRACKET) || this.checkType(tokens_1.TokenType.LBRACKET_DOUBLE)) {
1080
+ else if (s.checkType(tokens_1.TokenType.LBRACKET) || s.checkType(tokens_1.TokenType.LBRACKET_DOUBLE)) {
1708
1081
  bracketDepth += 1;
1709
1082
  }
1710
- else if (this.checkType(tokens_1.TokenType.RBRACKET) || this.checkType(tokens_1.TokenType.RBRACKET_DOUBLE)) {
1083
+ else if (s.checkType(tokens_1.TokenType.RBRACKET) || s.checkType(tokens_1.TokenType.RBRACKET_DOUBLE)) {
1711
1084
  bracketDepth = Math.max(0, bracketDepth - 1);
1712
1085
  }
1713
- this.advance();
1086
+ s.advance();
1714
1087
  }
1715
1088
  }
1716
1089
  }