@stevenvo780/st-lang 4.4.0 → 4.5.1

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 (158) hide show
  1. package/README.md +78 -37
  2. package/dist/coinduction/index.d.ts +136 -0
  3. package/dist/coinduction/index.d.ts.map +1 -0
  4. package/dist/coinduction/index.js +318 -0
  5. package/dist/coinduction/index.js.map +1 -0
  6. package/dist/combinators-ski/abstract.d.ts +5 -0
  7. package/dist/combinators-ski/abstract.d.ts.map +1 -0
  8. package/dist/combinators-ski/abstract.js +88 -0
  9. package/dist/combinators-ski/abstract.js.map +1 -0
  10. package/dist/combinators-ski/index.d.ts +6 -0
  11. package/dist/combinators-ski/index.d.ts.map +1 -0
  12. package/dist/combinators-ski/index.js +30 -0
  13. package/dist/combinators-ski/index.js.map +1 -0
  14. package/dist/combinators-ski/reduce.d.ts +10 -0
  15. package/dist/combinators-ski/reduce.d.ts.map +1 -0
  16. package/dist/combinators-ski/reduce.js +118 -0
  17. package/dist/combinators-ski/reduce.js.map +1 -0
  18. package/dist/combinators-ski/types.d.ts +23 -0
  19. package/dist/combinators-ski/types.d.ts.map +1 -0
  20. package/dist/combinators-ski/types.js +102 -0
  21. package/dist/combinators-ski/types.js.map +1 -0
  22. package/dist/constructive-reals/index.d.ts +132 -0
  23. package/dist/constructive-reals/index.d.ts.map +1 -0
  24. package/dist/constructive-reals/index.js +723 -0
  25. package/dist/constructive-reals/index.js.map +1 -0
  26. package/dist/game-semantics/convert.d.ts +4 -0
  27. package/dist/game-semantics/convert.d.ts.map +1 -0
  28. package/dist/game-semantics/convert.js +28 -0
  29. package/dist/game-semantics/convert.js.map +1 -0
  30. package/dist/game-semantics/index.d.ts +6 -0
  31. package/dist/game-semantics/index.d.ts.map +1 -0
  32. package/dist/game-semantics/index.js +28 -0
  33. package/dist/game-semantics/index.js.map +1 -0
  34. package/dist/game-semantics/strategy.d.ts +34 -0
  35. package/dist/game-semantics/strategy.d.ts.map +1 -0
  36. package/dist/game-semantics/strategy.js +336 -0
  37. package/dist/game-semantics/strategy.js.map +1 -0
  38. package/dist/game-semantics/types.d.ts +64 -0
  39. package/dist/game-semantics/types.d.ts.map +1 -0
  40. package/dist/game-semantics/types.js +78 -0
  41. package/dist/game-semantics/types.js.map +1 -0
  42. package/dist/higher-order-unify/index.d.ts +5 -0
  43. package/dist/higher-order-unify/index.d.ts.map +1 -0
  44. package/dist/higher-order-unify/index.js +27 -0
  45. package/dist/higher-order-unify/index.js.map +1 -0
  46. package/dist/higher-order-unify/normalize.d.ts +14 -0
  47. package/dist/higher-order-unify/normalize.d.ts.map +1 -0
  48. package/dist/higher-order-unify/normalize.js +191 -0
  49. package/dist/higher-order-unify/normalize.js.map +1 -0
  50. package/dist/higher-order-unify/pattern.d.ts +4 -0
  51. package/dist/higher-order-unify/pattern.d.ts.map +1 -0
  52. package/dist/higher-order-unify/pattern.js +70 -0
  53. package/dist/higher-order-unify/pattern.js.map +1 -0
  54. package/dist/higher-order-unify/types.d.ts +19 -0
  55. package/dist/higher-order-unify/types.d.ts.map +1 -0
  56. package/dist/higher-order-unify/types.js +14 -0
  57. package/dist/higher-order-unify/types.js.map +1 -0
  58. package/dist/higher-order-unify/unify.d.ts +5 -0
  59. package/dist/higher-order-unify/unify.d.ts.map +1 -0
  60. package/dist/higher-order-unify/unify.js +306 -0
  61. package/dist/higher-order-unify/unify.js.map +1 -0
  62. package/dist/index.d.ts +10 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +40 -1
  65. package/dist/index.js.map +1 -1
  66. package/dist/nbe/index.d.ts +3 -0
  67. package/dist/nbe/index.d.ts.map +1 -0
  68. package/dist/nbe/index.js +25 -0
  69. package/dist/nbe/index.js.map +1 -0
  70. package/dist/nbe/nbe.d.ts +7 -0
  71. package/dist/nbe/nbe.d.ts.map +1 -0
  72. package/dist/nbe/nbe.js +118 -0
  73. package/dist/nbe/nbe.js.map +1 -0
  74. package/dist/nbe/types.d.ts +54 -0
  75. package/dist/nbe/types.d.ts.map +1 -0
  76. package/dist/nbe/types.js +117 -0
  77. package/dist/nbe/types.js.map +1 -0
  78. package/dist/profile-bridge/index.d.ts +64 -0
  79. package/dist/profile-bridge/index.d.ts.map +1 -0
  80. package/dist/profile-bridge/index.js +328 -0
  81. package/dist/profile-bridge/index.js.map +1 -0
  82. package/dist/proof-nets/construct.d.ts +3 -0
  83. package/dist/proof-nets/construct.d.ts.map +1 -0
  84. package/dist/proof-nets/construct.js +85 -0
  85. package/dist/proof-nets/construct.js.map +1 -0
  86. package/dist/proof-nets/correctness.d.ts +3 -0
  87. package/dist/proof-nets/correctness.d.ts.map +1 -0
  88. package/dist/proof-nets/correctness.js +213 -0
  89. package/dist/proof-nets/correctness.js.map +1 -0
  90. package/dist/proof-nets/cut-elim.d.ts +9 -0
  91. package/dist/proof-nets/cut-elim.d.ts.map +1 -0
  92. package/dist/proof-nets/cut-elim.js +149 -0
  93. package/dist/proof-nets/cut-elim.js.map +1 -0
  94. package/dist/proof-nets/index.d.ts +6 -0
  95. package/dist/proof-nets/index.d.ts.map +1 -0
  96. package/dist/proof-nets/index.js +33 -0
  97. package/dist/proof-nets/index.js.map +1 -0
  98. package/dist/proof-nets/types.d.ts +36 -0
  99. package/dist/proof-nets/types.d.ts.map +1 -0
  100. package/dist/proof-nets/types.js +89 -0
  101. package/dist/proof-nets/types.js.map +1 -0
  102. package/dist/tableau-framework/TableauProver.d.ts +10 -0
  103. package/dist/tableau-framework/TableauProver.d.ts.map +1 -0
  104. package/dist/tableau-framework/TableauProver.js +118 -0
  105. package/dist/tableau-framework/TableauProver.js.map +1 -0
  106. package/dist/tableau-framework/index.d.ts +5 -0
  107. package/dist/tableau-framework/index.d.ts.map +1 -0
  108. package/dist/tableau-framework/index.js +11 -0
  109. package/dist/tableau-framework/index.js.map +1 -0
  110. package/dist/tableau-framework/propositional.d.ts +11 -0
  111. package/dist/tableau-framework/propositional.d.ts.map +1 -0
  112. package/dist/tableau-framework/propositional.js +143 -0
  113. package/dist/tableau-framework/propositional.js.map +1 -0
  114. package/dist/tableau-framework/types.d.ts +32 -0
  115. package/dist/tableau-framework/types.d.ts.map +1 -0
  116. package/dist/tableau-framework/types.js +6 -0
  117. package/dist/tableau-framework/types.js.map +1 -0
  118. package/dist/tests/coinduction/coinduction.test.d.ts +2 -0
  119. package/dist/tests/coinduction/coinduction.test.d.ts.map +1 -0
  120. package/dist/tests/coinduction/coinduction.test.js +217 -0
  121. package/dist/tests/coinduction/coinduction.test.js.map +1 -0
  122. package/dist/tests/combinators-ski/combinators-ski.test.d.ts +2 -0
  123. package/dist/tests/combinators-ski/combinators-ski.test.d.ts.map +1 -0
  124. package/dist/tests/combinators-ski/combinators-ski.test.js +211 -0
  125. package/dist/tests/combinators-ski/combinators-ski.test.js.map +1 -0
  126. package/dist/tests/constructive-reals/constructive-reals.test.d.ts +2 -0
  127. package/dist/tests/constructive-reals/constructive-reals.test.d.ts.map +1 -0
  128. package/dist/tests/constructive-reals/constructive-reals.test.js +357 -0
  129. package/dist/tests/constructive-reals/constructive-reals.test.js.map +1 -0
  130. package/dist/tests/game-semantics/game-semantics.test.d.ts +2 -0
  131. package/dist/tests/game-semantics/game-semantics.test.d.ts.map +1 -0
  132. package/dist/tests/game-semantics/game-semantics.test.js +143 -0
  133. package/dist/tests/game-semantics/game-semantics.test.js.map +1 -0
  134. package/dist/tests/higher-order-unify/ho-unify.test.d.ts +2 -0
  135. package/dist/tests/higher-order-unify/ho-unify.test.d.ts.map +1 -0
  136. package/dist/tests/higher-order-unify/ho-unify.test.js +264 -0
  137. package/dist/tests/higher-order-unify/ho-unify.test.js.map +1 -0
  138. package/dist/tests/integration/cross-modules.test.d.ts +8 -0
  139. package/dist/tests/integration/cross-modules.test.d.ts.map +1 -0
  140. package/dist/tests/integration/cross-modules.test.js +668 -0
  141. package/dist/tests/integration/cross-modules.test.js.map +1 -0
  142. package/dist/tests/nbe/nbe.test.d.ts +2 -0
  143. package/dist/tests/nbe/nbe.test.d.ts.map +1 -0
  144. package/dist/tests/nbe/nbe.test.js +121 -0
  145. package/dist/tests/nbe/nbe.test.js.map +1 -0
  146. package/dist/tests/profile-bridge/translations.test.d.ts +2 -0
  147. package/dist/tests/profile-bridge/translations.test.d.ts.map +1 -0
  148. package/dist/tests/profile-bridge/translations.test.js +266 -0
  149. package/dist/tests/profile-bridge/translations.test.js.map +1 -0
  150. package/dist/tests/proof-nets/proof-nets.test.d.ts +2 -0
  151. package/dist/tests/proof-nets/proof-nets.test.d.ts.map +1 -0
  152. package/dist/tests/proof-nets/proof-nets.test.js +263 -0
  153. package/dist/tests/proof-nets/proof-nets.test.js.map +1 -0
  154. package/dist/tests/tableau-framework/tableau.test.d.ts +2 -0
  155. package/dist/tests/tableau-framework/tableau.test.d.ts.map +1 -0
  156. package/dist/tests/tableau-framework/tableau.test.js +196 -0
  157. package/dist/tests/tableau-framework/tableau.test.js.map +1 -0
  158. package/package.json +2 -1
@@ -0,0 +1,723 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // ST Constructive Reals — Números reales computables
4
+ // ============================================================
5
+ // Cada real x se representa como una función `approxBig(n)` que
6
+ // devuelve un entero `b` tal que
7
+ //
8
+ // | x - b / 2^n | < 2^{-n}
9
+ //
10
+ // (es decir, una aproximación dyádica con cota de error explícita).
11
+ //
12
+ // La función `approx(p)` expuesta como API pública devuelve el par
13
+ // `{ numerator, denominator }` con `denominator = 2^p`, garantizando
14
+ // la misma cota de error |x - numerator/denominator| < 2^{-p}.
15
+ //
16
+ // Esto es esencialmente la formulación de Bishop/Bridges para los
17
+ // reales constructivos: secuencias de Cauchy con módulo explícito de
18
+ // convergencia. No usamos `number` (IEEE-754) excepto como entrada;
19
+ // internamente todo es `bigint`.
20
+ //
21
+ // Operaciones implementadas (todas devuelven CReal):
22
+ // fromInt, fromRational, neg, abs
23
+ // add, sub, mul, div (div: requiere b ≠ 0)
24
+ // sqrt (requiere x ≥ 0)
25
+ // PI, E, SQRT2 (constantes)
26
+ // compareWithEpsilon, toString
27
+ //
28
+ // Decisiones de implementación:
29
+ // • Internamente usamos cache memoizado por precisión: una vez
30
+ // calculada una aproximación a precisión n, queda guardada.
31
+ // Esto evita recomputar series largas para PI/E al imprimirlas.
32
+ // • Las operaciones binarias piden a sus operandos precisiones
33
+ // mayores (precisión de trabajo) tal que el error acumulado
34
+ // siga acotado por 2^{-p} en el resultado.
35
+ // • Para mul/div necesitamos cotas superiores/inferiores sobre
36
+ // |a| y |b|; las obtenemos consultando una aproximación gruesa
37
+ // primero, ajustando el tamaño en bits.
38
+ //
39
+ // Nota sobre redondeo: usamos "round half away from zero" para
40
+ // convertir un entero escalado de precisión `n+k` a `n`. La cota
41
+ // de error de redondeo es entonces ≤ 1/2 en la unidad de precisión
42
+ // `n`, equivalente a 2^{-(n+1)}.
43
+ // ============================================================
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.__internals = exports.SQRT2 = exports.E = exports.PI = void 0;
46
+ exports.fromInt = fromInt;
47
+ exports.fromRational = fromRational;
48
+ exports.neg = neg;
49
+ exports.abs = abs;
50
+ exports.add = add;
51
+ exports.sub = sub;
52
+ exports.mul = mul;
53
+ exports.div = div;
54
+ exports.sqrt = sqrt;
55
+ exports.compareWithEpsilon = compareWithEpsilon;
56
+ exports.toString = toString;
57
+ exports.exp = exp;
58
+ exports.log = log;
59
+ exports.sin = sin;
60
+ exports.cos = cos;
61
+ exports.pow = pow;
62
+ // ── Helpers internos ────────────────────────────────────────
63
+ /** Eleva 2 a un entero no negativo. */
64
+ function pow2(n) {
65
+ if (n < 0)
66
+ throw new RangeError(`pow2: n debe ser >= 0, recibí ${n}`);
67
+ return 1n << BigInt(n);
68
+ }
69
+ /**
70
+ * Divide entero con "round half away from zero".
71
+ * shiftRight(x, k) ≈ x / 2^k redondeado.
72
+ * Garantiza |shiftRight(x,k) - x/2^k| ≤ 1/2.
73
+ */
74
+ function shiftRight(x, k) {
75
+ if (k <= 0)
76
+ return x << BigInt(-k);
77
+ const half = 1n << BigInt(k - 1);
78
+ return x >= 0n ? (x + half) >> BigInt(k) : -(((-x) + half) >> BigInt(k));
79
+ }
80
+ /**
81
+ * Calcula el número de bits del entero (|x| en binario).
82
+ * bitLength(0) = 0, bitLength(1) = 1, bitLength(7) = 3, bitLength(8) = 4.
83
+ */
84
+ function bitLength(x) {
85
+ if (x < 0n)
86
+ x = -x;
87
+ if (x === 0n)
88
+ return 0;
89
+ // Toma el string binario; para bigint muy grandes podríamos
90
+ // hacer un loop, pero `toString(2).length` es eficiente.
91
+ return x.toString(2).length;
92
+ }
93
+ /**
94
+ * Construye un CReal a partir de la función interna scaled (bigint).
95
+ * approxBig(n) debe satisfacer |x - approxBig(n) / 2^n| < 2^{-n}.
96
+ *
97
+ * Memoiza por valor de `n` para no recomputar.
98
+ */
99
+ function makeCReal(approxBig) {
100
+ const cache = new Map();
101
+ function getBig(n) {
102
+ if (n < 0) {
103
+ // Para precisión negativa simplemente desplazamos a la baja.
104
+ const v = getBig(0);
105
+ return shiftRight(v, -n);
106
+ }
107
+ const cached = cache.get(n);
108
+ if (cached !== undefined)
109
+ return cached;
110
+ const v = approxBig(n);
111
+ cache.set(n, v);
112
+ return v;
113
+ }
114
+ // Exponemos también approxBig internamente vía un símbolo "interno"
115
+ // para que las operaciones lo aprovechen sin parsear el objeto público.
116
+ const r = {
117
+ approx(precision) {
118
+ const num = getBig(precision);
119
+ const denom = precision >= 0 ? pow2(precision) : 1n;
120
+ // Si precision < 0, "denominador 2^p" no es entero; convertimos
121
+ // a forma estándar denominador 1 y multiplicador del lado num.
122
+ // (Caso raro pero correcto: num = round(x / 2^{-p}).)
123
+ if (precision < 0) {
124
+ return { numerator: num, denominator: 1n };
125
+ }
126
+ return { numerator: num, denominator: denom };
127
+ },
128
+ };
129
+ r.__approxBig = getBig;
130
+ return r;
131
+ }
132
+ /** Extrae el accessor bigint interno de un CReal creado por makeCReal. */
133
+ function approxBigOf(r) {
134
+ const fn = r.__approxBig;
135
+ if (fn)
136
+ return fn;
137
+ // Fallback (CReal externo no creado por makeCReal): reconstruye desde approx().
138
+ return (n) => {
139
+ const { numerator, denominator } = r.approx(n);
140
+ // numerator/denominator ≈ x, queremos round(x * 2^n).
141
+ // Si denominator = 2^n exactamente, numerator ya está en esa escala.
142
+ if (denominator === pow2(n))
143
+ return numerator;
144
+ // Caso general: round(numerator * 2^n / denominator).
145
+ const scaled = numerator * pow2(Math.max(n, 0));
146
+ const half = denominator / 2n;
147
+ return numerator >= 0n
148
+ ? (scaled + half) / denominator
149
+ : -(((-scaled) + half) / denominator);
150
+ };
151
+ }
152
+ // ── Constructores ───────────────────────────────────────────
153
+ function fromInt(n) {
154
+ const v = typeof n === 'bigint' ? n : BigInt(Math.trunc(n));
155
+ if (typeof n === 'number' && !Number.isFinite(n)) {
156
+ throw new RangeError(`fromInt: número no finito ${n}`);
157
+ }
158
+ if (typeof n === 'number' && !Number.isInteger(n)) {
159
+ throw new RangeError(`fromInt: esperaba entero, recibí ${n}`);
160
+ }
161
+ return makeCReal((prec) => v << BigInt(Math.max(prec, 0)));
162
+ }
163
+ function fromRational(p, q) {
164
+ const num = typeof p === 'bigint' ? p : BigInt(Math.trunc(p));
165
+ const denom = typeof q === 'bigint' ? q : BigInt(Math.trunc(q));
166
+ if (typeof p === 'number' && !Number.isInteger(p)) {
167
+ throw new RangeError(`fromRational: numerador no entero ${p}`);
168
+ }
169
+ if (typeof q === 'number' && !Number.isInteger(q)) {
170
+ throw new RangeError(`fromRational: denominador no entero ${q}`);
171
+ }
172
+ if (denom === 0n)
173
+ throw new RangeError('fromRational: denominador 0');
174
+ // Normalizamos signo: denom > 0.
175
+ const sign = denom < 0n ? -1n : 1n;
176
+ const n0 = num * sign;
177
+ const d0 = denom * sign;
178
+ return makeCReal((prec) => {
179
+ // round(num/denom * 2^prec) = round(num * 2^prec / denom).
180
+ const p = Math.max(prec, 0);
181
+ const scaled = n0 << BigInt(p);
182
+ const half = d0 >> 1n; // floor(d0/2). suficiente para round-half-to-even? usamos away-from-zero.
183
+ return n0 >= 0n
184
+ ? (scaled + half) / d0
185
+ : -(((-scaled) + half) / d0);
186
+ });
187
+ }
188
+ // ── Operaciones aritméticas ────────────────────────────────
189
+ function neg(a) {
190
+ const aa = approxBigOf(a);
191
+ return makeCReal((prec) => -aa(prec));
192
+ }
193
+ function abs(a) {
194
+ const aa = approxBigOf(a);
195
+ return makeCReal((prec) => {
196
+ const v = aa(prec);
197
+ return v < 0n ? -v : v;
198
+ });
199
+ }
200
+ /**
201
+ * add(a,b) a precisión p:
202
+ * pedimos a y b a precisión p+2.
203
+ * error de cada uno < 2^{-(p+2)} → error en a+b < 2·2^{-(p+2)} = 2^{-(p+1)}.
204
+ * Al pasar de escala p+2 a p (shift de 2), introducimos error
205
+ * de redondeo ≤ 1/2 en la unidad p, = 2^{-(p+1)}.
206
+ * Total: < 2^{-(p+1)} + 2^{-(p+1)} = 2^{-p}. ✓
207
+ */
208
+ function add(a, b) {
209
+ const aa = approxBigOf(a);
210
+ const bb = approxBigOf(b);
211
+ return makeCReal((prec) => {
212
+ const work = prec + 2;
213
+ const s = aa(work) + bb(work);
214
+ return shiftRight(s, 2);
215
+ });
216
+ }
217
+ function sub(a, b) {
218
+ const aa = approxBigOf(a);
219
+ const bb = approxBigOf(b);
220
+ return makeCReal((prec) => {
221
+ const work = prec + 2;
222
+ const s = aa(work) - bb(work);
223
+ return shiftRight(s, 2);
224
+ });
225
+ }
226
+ /**
227
+ * mul(a,b) a precisión p:
228
+ * Necesitamos cotas sobre |a| y |b|. Tomamos una aproximación gruesa
229
+ * a precisión 0 para estimar el tamaño en bits.
230
+ * Sean |a| ≤ 2^A, |b| ≤ 2^B (con A,B no-negativos).
231
+ * Trabajamos a precisión p + A + B + 3.
232
+ * En esa escala el producto cabe y la cota de error queda < 2^{-p}.
233
+ *
234
+ * Detalle del error: si â = a + ε_a con |ε_a| < 2^{-w} y análogamente
235
+ * para b̂ (w = work precision en los operandos), entonces
236
+ * â·b̂ - a·b = a·ε_b + b·ε_a + ε_a·ε_b.
237
+ * |a·ε_b| ≤ 2^A · 2^{-w}, idem para b.
238
+ * Eligiendo w = p + A + B + 3 ese error queda < 2·2^{-(p+B+3)}
239
+ * acotado holgadamente por 2^{-(p+1)}, y el shift final añade otro
240
+ * 2^{-(p+1)}, dando < 2^{-p}.
241
+ */
242
+ function mul(a, b) {
243
+ const aa = approxBigOf(a);
244
+ const bb = approxBigOf(b);
245
+ return makeCReal((prec) => {
246
+ // Estimamos cota superior en bits para |a| y |b| con una aprox gruesa.
247
+ // aa(8) ≈ round(a * 256). bitLength(aa(8)) - 8 ≈ ceil(log2|a|).
248
+ const probePrec = 8;
249
+ const aProbe = aa(probePrec);
250
+ const bProbe = bb(probePrec);
251
+ // |a| ≤ (|aProbe| + 1) / 2^probePrec. Así A_bits cubre eso.
252
+ const aBits = Math.max(0, bitLength(aProbe) - probePrec + 1);
253
+ const bBits = Math.max(0, bitLength(bProbe) - probePrec + 1);
254
+ const work = Math.max(prec + aBits + bBits + 4, 4);
255
+ const aw = aa(work);
256
+ const bw = bb(work);
257
+ // aw * bw ≈ a * b * 2^{2·work}. Queremos resultado en escala 2^prec.
258
+ // → shift right (2·work - prec).
259
+ const product = aw * bw;
260
+ return shiftRight(product, 2 * work - prec);
261
+ });
262
+ }
263
+ /**
264
+ * Encuentra un k ≥ 0 tal que |b| ≥ 2^{-k} (es decir, b está acotado
265
+ * lejos de cero por 2^{-k}). Para ello escaneamos precisiones
266
+ * crecientes hasta que la aproximación sea claramente distinta de cero.
267
+ * Si b es realmente cero, esto diverge — el caller debe asegurar b ≠ 0.
268
+ */
269
+ function findLowerBoundExp(b, maxK = 4096) {
270
+ let k = 4;
271
+ while (k <= maxK) {
272
+ const v = b(k);
273
+ // |v| ≥ 2 garantiza |b - v/2^k| < 2^{-k} → |b| ≥ |v|/2^k - 2^{-k} ≥ 2^{-k}.
274
+ if (v > 1n || v < -1n)
275
+ return k;
276
+ k *= 2;
277
+ }
278
+ throw new RangeError('div/findLowerBoundExp: no pude separar el divisor de cero — ' +
279
+ 'probablemente es 0 o demasiado pequeño');
280
+ }
281
+ /**
282
+ * div(a,b) a precisión p (b ≠ 0).
283
+ * Encontramos k tal que |b| ≥ 2^{-k}.
284
+ * Necesitamos también cota superior A_bits sobre |a|.
285
+ * Trabajamos a precisión w = p + 2k + A_bits + 4.
286
+ *
287
+ * Si â = a + ε_a, b̂ = b + ε_b, entonces
288
+ * â/b̂ - a/b = (ε_a · b - a · ε_b) / (b · b̂).
289
+ * |b · b̂| ≥ (2^{-k}) · (2^{-k} - 2^{-w}) ≥ 2^{-2k-1}.
290
+ * |ε_a · b| ≤ 2^{-w} · (|b̂|+2^{-w}).
291
+ * |a · ε_b| ≤ |â+2^{-w}| · 2^{-w}.
292
+ * Tomando w = p + 2k + A_bits + 4 acotamos por < 2^{-p}.
293
+ */
294
+ function div(a, b) {
295
+ const aa = approxBigOf(a);
296
+ const bb = approxBigOf(b);
297
+ return makeCReal((prec) => {
298
+ const k = findLowerBoundExp(bb);
299
+ const probePrec = 8;
300
+ const aProbe = aa(probePrec);
301
+ const aBits = Math.max(0, bitLength(aProbe) - probePrec + 1);
302
+ const work = Math.max(prec + 2 * k + aBits + 4, 4);
303
+ const aw = aa(work);
304
+ const bw = bb(work);
305
+ if (bw === 0n) {
306
+ // Sólo debería pasar si findLowerBoundExp falló silenciosamente.
307
+ throw new RangeError('div: divisor evaluado a 0 a precisión de trabajo');
308
+ }
309
+ // (aw/2^work) / (bw/2^work) = aw/bw. Queremos round(aw/bw * 2^prec).
310
+ // = round(aw * 2^prec / bw).
311
+ const numScaled = aw << BigInt(Math.max(prec, 0));
312
+ const absDen = bw < 0n ? -bw : bw;
313
+ const absNum = numScaled < 0n ? -numScaled : numScaled;
314
+ const half = absDen >> 1n;
315
+ // round-half-away-from-zero.
316
+ const signNum = numScaled < 0n ? -1n : 1n;
317
+ const signDen = bw < 0n ? -1n : 1n;
318
+ const q = (absNum + half) / absDen;
319
+ return signNum * signDen * q;
320
+ });
321
+ }
322
+ /**
323
+ * sqrt(a) para a ≥ 0. Si a < 0 (detectado con cota), lanza.
324
+ * Implementación: Newton-Raphson en bigint sobre x² = N donde
325
+ * N = aprox(a) a precisión 2·prec + buffer. La raíz cuadrada entera
326
+ * de N da nuestra aproximación a √a a precisión prec.
327
+ */
328
+ function sqrt(a) {
329
+ const aa = approxBigOf(a);
330
+ return makeCReal((prec) => {
331
+ // Pedimos a a precisión 2·prec + 4 para tener margen.
332
+ const work = 2 * Math.max(prec, 0) + 4;
333
+ const aw = aa(work);
334
+ if (aw < 0n) {
335
+ // Podría ser a ≈ 0 desde abajo por ruido de aproximación. Tolerar
336
+ // -1 (que corresponde a a ∈ (-2^{-work}, 0]) como cero.
337
+ if (aw > -4n)
338
+ return 0n;
339
+ throw new RangeError(`sqrt: a < 0 (aproximación = ${aw}/2^${work})`);
340
+ }
341
+ // √(aw/2^work) ≈ √aw / 2^{work/2}. Como work es par, scale = work/2.
342
+ const scale = work / 2;
343
+ // Queremos round(√aw). Newton sobre enteros.
344
+ const rootInt = isqrt(aw);
345
+ // rootInt = floor(√aw). Equivalente en escala scale.
346
+ // Resultado en escala prec: shift de (scale - prec) bits a la derecha.
347
+ return shiftRight(rootInt, scale - prec);
348
+ });
349
+ }
350
+ /** Raíz cuadrada entera (floor) de n ≥ 0 vía Newton. */
351
+ function isqrt(n) {
352
+ if (n < 0n)
353
+ throw new RangeError('isqrt: n < 0');
354
+ if (n < 2n)
355
+ return n;
356
+ // Estimación inicial: 2^(ceil(bits/2)).
357
+ const bits = bitLength(n);
358
+ let x = 1n << BigInt(Math.ceil(bits / 2));
359
+ // Newton: x_{k+1} = (x_k + n/x_k) / 2. Converge cuadráticamente.
360
+ while (true) {
361
+ const next = (x + n / x) >> 1n;
362
+ if (next >= x)
363
+ break;
364
+ x = next;
365
+ }
366
+ return x;
367
+ }
368
+ // ── Comparación ────────────────────────────────────────────
369
+ /**
370
+ * compareWithEpsilon(a, b, epsPrec):
371
+ * Si |a - b| < 2^{-epsPrec}, devuelve 0 (indistinguibles).
372
+ * Si a > b + 2^{-epsPrec}, devuelve 1.
373
+ * Si a < b - 2^{-epsPrec}, devuelve -1.
374
+ *
375
+ * Implementación: comparamos aproximaciones a precisión epsPrec + 3.
376
+ * |aw/2^w - a| < 2^{-w}, idem b. Entonces
377
+ * (aw - bw)/2^w está dentro de (a - b) ± 2·2^{-w}.
378
+ * Eligiendo w = epsPrec + 3:
379
+ * • Si (aw - bw) > 2^{w - epsPrec} + 2 = 8 + 2 = 10 (en escala w),
380
+ * entonces a - b > 2^{-epsPrec}, devolvemos 1.
381
+ * • Análogo para -10.
382
+ * • En otro caso, devolvemos 0.
383
+ */
384
+ function compareWithEpsilon(a, b, epsilonPrecision) {
385
+ const aa = approxBigOf(a);
386
+ const bb = approxBigOf(b);
387
+ const w = epsilonPrecision + 3;
388
+ const diff = aa(w) - bb(w);
389
+ // 2^{-epsilonPrecision} en escala 2^{-w} = 2^{w - epsilonPrecision} = 2^3 = 8.
390
+ // Margen de 2 por el error doble de aproximación.
391
+ const threshold = 8n + 2n;
392
+ if (diff > threshold)
393
+ return 1;
394
+ if (diff < -threshold)
395
+ return -1;
396
+ return 0;
397
+ }
398
+ // ── Representación decimal ─────────────────────────────────
399
+ /**
400
+ * toString(r, digits): representación decimal con `digits` dígitos
401
+ * después del punto. Usa precisión binaria suficiente:
402
+ * 2^p > 10^digits ⇔ p > digits · log2(10) ≈ digits · 3.322.
403
+ * Tomamos p = ceil(digits · 4) + 8 para holgura.
404
+ */
405
+ function toString(r, digits) {
406
+ if (digits < 0)
407
+ throw new RangeError(`toString: digits debe ser ≥ 0, recibí ${digits}`);
408
+ const prec = Math.ceil(digits * 4) + 8;
409
+ const { numerator, denominator } = r.approx(prec);
410
+ // Queremos floor(numerator * 10^digits / denominator), con signo.
411
+ const sign = numerator < 0n ? '-' : '';
412
+ const absNum = numerator < 0n ? -numerator : numerator;
413
+ const tenPow = 10n ** BigInt(digits);
414
+ // round-half-away-from-zero al pasar a base-10.
415
+ const half = denominator / 2n;
416
+ const scaled = (absNum * tenPow + half) / denominator;
417
+ const s = scaled.toString().padStart(digits + 1, '0');
418
+ if (digits === 0)
419
+ return sign + s;
420
+ const intPart = s.slice(0, s.length - digits);
421
+ const fracPart = s.slice(s.length - digits);
422
+ return sign + intPart + '.' + fracPart;
423
+ }
424
+ // ── Transcendentales ───────────────────────────────────────
425
+ //
426
+ // Implementamos exp, log (ln), sin, cos vía expansiones en serie
427
+ // con reducción de argumento. Mantenemos las pruebas formales del
428
+ // error en los comentarios; el patrón es similar al de PI/E:
429
+ // • escala 2^work con work = prec + buffer
430
+ // • sumar términos hasta que |término| < 1 en esa escala
431
+ // • el buffer absorbe el error acumulado de divisiones enteras.
432
+ /**
433
+ * exp(x) = Σ x^k / k!. Para que la serie converja rápido reducimos
434
+ * primero el argumento: escribimos x = q · ln(2) + r con |r| ≤ ln(2)/2
435
+ * usando q = round(x / ln(2)). Luego exp(x) = 2^q · exp(r).
436
+ *
437
+ * Para esta versión inicial hacemos una reducción más simple: si
438
+ * |x| > 1, dividimos por 2^k hasta que |x/2^k| < 1, calculamos
439
+ * exp(x/2^k) por serie, y elevamos al cuadrado k veces (exp(y)² = exp(2y)).
440
+ * Esto mantiene la convergencia de la serie acotada a ~prec términos.
441
+ */
442
+ function exp(x) {
443
+ const xa = approxBigOf(x);
444
+ return makeCReal((prec) => {
445
+ // Estimar |x| con aproximación gruesa.
446
+ const probePrec = 8;
447
+ const xProbe = xa(probePrec);
448
+ const xBits = bitLength(xProbe) - probePrec; // ≈ log2(|x|)
449
+ // k tal que |x/2^k| ≤ 1/2. Si xBits ≤ -1, ya está bien.
450
+ const k = Math.max(0, xBits + 2);
451
+ const work = prec + k + 24;
452
+ // y = x / 2^k, en escala 2^work: yScaled = aprox(x, work) >> k.
453
+ const xWork = xa(work);
454
+ const yScaled = shiftRight(xWork, k);
455
+ // Serie: e^y en escala 2^work.
456
+ // sum_0 = 2^work
457
+ // term_{n+1} = term_n · y / (n+1) donde term_n está en escala 2^work
458
+ // e y en escala 2^work
459
+ // ⇒ multiplicar y dividir por 2^work.
460
+ let sum = pow2(work);
461
+ let term = pow2(work);
462
+ let n = 1n;
463
+ while (term !== 0n) {
464
+ term = (term * yScaled) / pow2(work) / n;
465
+ sum += term;
466
+ n += 1n;
467
+ // Cota de seguridad: si la serie no decae (no debería pasar con |y|≤1/2),
468
+ // salimos al llegar a ~prec términos.
469
+ if (n > BigInt(prec + 200))
470
+ break;
471
+ }
472
+ // Ahora elevamos al cuadrado k veces para recuperar e^x.
473
+ let result = sum;
474
+ for (let i = 0; i < k; i++) {
475
+ // (result/2^work)² = result²/2^{2·work}, en escala 2^work necesitamos /2^work.
476
+ result = (result * result) / pow2(work);
477
+ }
478
+ return shiftRight(result, work - prec);
479
+ });
480
+ }
481
+ /**
482
+ * log(x) = ln(x), para x > 0. Reducimos a [1, 2) escribiendo x = 2^k · m,
483
+ * luego ln(x) = k·ln(2) + ln(m). Para ln(m) con m ∈ [1, 2) usamos
484
+ * ln(1+u) = u - u²/2 + u³/3 - …, con u = m - 1 ∈ [0, 1).
485
+ * Converge lento para u cerca de 1; aceptable para este nivel.
486
+ *
487
+ * Para ln(2) usamos la serie atanh: ln(2) = 2·atanh(1/3) = 2·(1/3 + 1/(3·27) + …).
488
+ */
489
+ function lnHalf(n) {
490
+ // ln(2) en escala 2^n. atanh(1/3) = Σ 1/((2k+1)·3^{2k+1}).
491
+ const scale = pow2(n);
492
+ let sum = 0n;
493
+ let xPow = scale / 3n; // 1/3 en escala 2^n.
494
+ let k = 0n;
495
+ while (xPow !== 0n) {
496
+ sum += xPow / (2n * k + 1n);
497
+ xPow = xPow / 9n;
498
+ k += 1n;
499
+ }
500
+ return 2n * sum;
501
+ }
502
+ function log(x) {
503
+ const xa = approxBigOf(x);
504
+ return makeCReal((prec) => {
505
+ const probePrec = 8;
506
+ const xProbe = xa(probePrec);
507
+ if (xProbe <= 0n) {
508
+ // Necesitamos x > 0 estrictamente. Refinemos para no rechazar
509
+ // por ruido en el probe.
510
+ const refined = xa(prec + 4);
511
+ if (refined <= 1n) {
512
+ throw new RangeError(`log: x debe ser > 0, aproximación = ${refined}/2^${prec + 4}`);
513
+ }
514
+ }
515
+ const work = prec + 32;
516
+ const xWork = xa(work);
517
+ // Encontrar k tal que xWork / 2^work ∈ [1, 2): k = bitLength(xWork) - work - 1.
518
+ // (porque 2^{bitLength-1} ≤ xWork < 2^bitLength.)
519
+ const k = bitLength(xWork) - work - 1;
520
+ // m = x / 2^k, en escala 2^work: mScaled = xWork con shift.
521
+ const mScaled = k >= 0 ? xWork >> BigInt(k) : xWork << BigInt(-k);
522
+ // u = m - 1 en escala 2^work.
523
+ const uScaled = mScaled - pow2(work);
524
+ // ln(m) = u - u²/2 + u³/3 - …
525
+ let sum = 0n;
526
+ let uPow = uScaled;
527
+ let n = 1n;
528
+ let sign = 1n;
529
+ const safety = BigInt(work * 4 + 200);
530
+ while (uPow !== 0n) {
531
+ sum += (sign * uPow) / n;
532
+ uPow = (uPow * uScaled) / pow2(work);
533
+ sign = -sign;
534
+ n += 1n;
535
+ if (n > safety)
536
+ break;
537
+ }
538
+ // ln(x) = k·ln(2) + sum.
539
+ const ln2 = lnHalf(work);
540
+ const total = BigInt(k) * ln2 + sum;
541
+ return shiftRight(total, work - prec);
542
+ });
543
+ }
544
+ /**
545
+ * sin(x), cos(x) vía serie de Taylor con reducción de argumento
546
+ * a [-π, π] por sustracción de múltiplos de 2π, y luego a
547
+ * [-π/4, π/4] para acelerar convergencia.
548
+ *
549
+ * Para mantener la implementación contenida, hacemos solo la
550
+ * primera reducción usando π precomputada a la precisión de trabajo.
551
+ */
552
+ function sinSeries(xScaled, work) {
553
+ // Σ (-1)^k x^{2k+1} / (2k+1)!. Asume |x/2^work| ≤ π.
554
+ const scale = pow2(work);
555
+ let sum = xScaled;
556
+ let term = xScaled;
557
+ let k = 1n;
558
+ let sign = -1n;
559
+ const xSq = (xScaled * xScaled) / scale;
560
+ while (term !== 0n) {
561
+ term = (term * xSq) / scale / ((2n * k) * (2n * k + 1n));
562
+ sum += sign * term;
563
+ sign = -sign;
564
+ k += 1n;
565
+ if (k > BigInt(work * 2 + 200))
566
+ break;
567
+ }
568
+ return sum;
569
+ }
570
+ function cosSeries(xScaled, work) {
571
+ const scale = pow2(work);
572
+ let sum = scale;
573
+ let term = scale;
574
+ let k = 1n;
575
+ let sign = -1n;
576
+ const xSq = (xScaled * xScaled) / scale;
577
+ while (term !== 0n) {
578
+ term = (term * xSq) / scale / ((2n * k - 1n) * (2n * k));
579
+ sum += sign * term;
580
+ sign = -sign;
581
+ k += 1n;
582
+ if (k > BigInt(work * 2 + 200))
583
+ break;
584
+ }
585
+ return sum;
586
+ }
587
+ function sin(x) {
588
+ const xa = approxBigOf(x);
589
+ return makeCReal((prec) => {
590
+ const work = prec + 32;
591
+ const xWork = xa(work);
592
+ // Reducir mod 2π: q = round(x / (2π)).
593
+ const piScaled = computePiAtPrecision(work);
594
+ const twoPi = 2n * piScaled;
595
+ // q en bigint: round(xWork / twoPi).
596
+ const half = (twoPi < 0n ? -twoPi : twoPi) >> 1n;
597
+ const absX = xWork < 0n ? -xWork : xWork;
598
+ const absQ = (absX + half) / twoPi;
599
+ const q = xWork < 0n ? -absQ : absQ;
600
+ const reduced = xWork - q * twoPi; // ∈ [-π, π] aproximadamente.
601
+ const result = sinSeries(reduced, work);
602
+ return shiftRight(result, work - prec);
603
+ });
604
+ }
605
+ function cos(x) {
606
+ const xa = approxBigOf(x);
607
+ return makeCReal((prec) => {
608
+ const work = prec + 32;
609
+ const xWork = xa(work);
610
+ const piScaled = computePiAtPrecision(work);
611
+ const twoPi = 2n * piScaled;
612
+ const half = twoPi >> 1n;
613
+ const absX = xWork < 0n ? -xWork : xWork;
614
+ const absQ = (absX + half) / twoPi;
615
+ const q = xWork < 0n ? -absQ : absQ;
616
+ const reduced = xWork - q * twoPi;
617
+ const result = cosSeries(reduced, work);
618
+ return shiftRight(result, work - prec);
619
+ });
620
+ }
621
+ /**
622
+ * pow(a, b) = exp(b · log(a)) para a > 0.
623
+ * Caso especial: si b es un entero, hacemos exponenciación rápida
624
+ * sobre CReal para evitar log de a (lo que permite a ≤ 0 si b es entero).
625
+ */
626
+ function pow(a, b) {
627
+ // Caso b entero: repetir multiplicación.
628
+ if (typeof b === 'number' && Number.isInteger(b)) {
629
+ if (b === 0)
630
+ return fromInt(1);
631
+ if (b < 0)
632
+ return div(fromInt(1), pow(a, -b));
633
+ // b > 0 entero: exponenciación rápida.
634
+ let result = fromInt(1);
635
+ let base = a;
636
+ let exponent = b;
637
+ while (exponent > 0) {
638
+ if (exponent & 1)
639
+ result = mul(result, base);
640
+ base = mul(base, base);
641
+ exponent = exponent >>> 1;
642
+ }
643
+ return result;
644
+ }
645
+ // Caso general: pow(a, b) = exp(b · log(a)).
646
+ const bReal = typeof b === 'number' ? fromRational(Math.round(b * 1e9), 1e9) : b;
647
+ return exp(mul(bReal, log(a)));
648
+ }
649
+ // ── Constantes ─────────────────────────────────────────────
650
+ /**
651
+ * PI vía la serie de Machin:
652
+ * π/4 = 4·arctan(1/5) - arctan(1/239)
653
+ * arctan(1/x) = 1/x - 1/(3·x³) + 1/(5·x⁵) - …
654
+ * Esta serie converge muy rápido para x grande (≈ log_x(2^p) términos).
655
+ *
656
+ * Implementación: calculamos arctan(1/x) escalado por 2^prec en bigint.
657
+ */
658
+ function arctanReciprocal(x, prec) {
659
+ // arctan(1/x) en escala 2^prec.
660
+ // Sumando_k = (-1)^k / ((2k+1) · x^{2k+1}) → escalado: 2^prec / ((2k+1) · x^{2k+1})
661
+ // Truncamos cuando |sumando| < 1 (en escala 2^prec).
662
+ const scale = pow2(prec);
663
+ let sum = 0n;
664
+ const xSq = x * x;
665
+ let term = scale / x; // primer término positivo: 2^prec / x.
666
+ let k = 0n;
667
+ let sign = 1n;
668
+ while (term !== 0n) {
669
+ const denom = 2n * k + 1n;
670
+ sum += (sign * term) / denom;
671
+ term = term / xSq;
672
+ sign = -sign;
673
+ k += 1n;
674
+ }
675
+ return sum;
676
+ }
677
+ function computePiAtPrecision(prec) {
678
+ // Trabajamos con buffer extra para que el error acumulado por la
679
+ // suma de muchas divisiones enteras quede dominado.
680
+ const work = prec + 16;
681
+ const at1_5 = arctanReciprocal(5n, work);
682
+ const at1_239 = arctanReciprocal(239n, work);
683
+ // π = 4 · (4·at(1/5) - at(1/239))
684
+ const piWork = 4n * (4n * at1_5 - at1_239);
685
+ return shiftRight(piWork, work - prec);
686
+ }
687
+ exports.PI = makeCReal(computePiAtPrecision);
688
+ /**
689
+ * E vía la serie e = Σ 1/k!. Trunca cuando 1/k! < 2^{-prec}.
690
+ */
691
+ function computeEAtPrecision(prec) {
692
+ const work = prec + 16;
693
+ const scale = pow2(work);
694
+ let sum = 0n;
695
+ let term = scale; // k=0: 1/0! = 1.
696
+ let k = 1n;
697
+ while (term !== 0n) {
698
+ sum += term;
699
+ term = term / k;
700
+ k += 1n;
701
+ }
702
+ return shiftRight(sum, work - prec);
703
+ }
704
+ exports.E = makeCReal(computeEAtPrecision);
705
+ /**
706
+ * SQRT2 = sqrt(2). Se construye directamente desde sqrt(fromInt(2))
707
+ * pero exponemos un cálculo dedicado vía isqrt para evitar la indirección.
708
+ */
709
+ function computeSqrt2AtPrecision(prec) {
710
+ // √2 en escala 2^prec = floor(√(2 · 2^{2·prec})) = isqrt(2^{2·prec+1}).
711
+ const big = pow2(2 * prec + 1);
712
+ return isqrt(big);
713
+ }
714
+ exports.SQRT2 = makeCReal(computeSqrt2AtPrecision);
715
+ // ── Exportación de utilidades internas para tests ──────────
716
+ /** @internal Exposed for whitebox tests. */
717
+ exports.__internals = {
718
+ shiftRight,
719
+ bitLength,
720
+ isqrt,
721
+ pow2,
722
+ };
723
+ //# sourceMappingURL=index.js.map