@cortex-js/compute-engine 0.58.0 → 0.59.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 (270) hide show
  1. package/README.md +4 -0
  2. package/dist/compile.esm.js +1721 -483
  3. package/dist/compile.min.esm.js +122 -74
  4. package/dist/compile.min.umd.cjs +122 -74
  5. package/dist/compile.umd.cjs +1721 -483
  6. package/dist/compute-engine.esm.js +25209 -22883
  7. package/dist/compute-engine.min.esm.js +135 -87
  8. package/dist/compute-engine.min.umd.cjs +135 -87
  9. package/dist/compute-engine.umd.cjs +24952 -22626
  10. package/dist/core.esm.js +25208 -22882
  11. package/dist/core.min.esm.js +134 -86
  12. package/dist/core.min.umd.cjs +134 -86
  13. package/dist/core.umd.cjs +24951 -22625
  14. package/dist/identities.esm.js +1921 -0
  15. package/dist/identities.min.esm.js +2 -0
  16. package/dist/identities.min.umd.cjs +4 -0
  17. package/dist/identities.umd.cjs +1946 -0
  18. package/dist/interval.esm.js +653 -330
  19. package/dist/interval.min.esm.js +8 -8
  20. package/dist/interval.min.umd.cjs +8 -8
  21. package/dist/interval.umd.cjs +653 -330
  22. package/dist/latex-syntax.esm.js +758 -512
  23. package/dist/latex-syntax.min.esm.js +7 -7
  24. package/dist/latex-syntax.min.umd.cjs +7 -7
  25. package/dist/latex-syntax.umd.cjs +758 -512
  26. package/dist/math-json.esm.js +8 -12
  27. package/dist/math-json.min.esm.js +2 -2
  28. package/dist/math-json.min.umd.cjs +2 -2
  29. package/dist/math-json.umd.cjs +8 -12
  30. package/dist/numerics.esm.js +1349 -228
  31. package/dist/numerics.min.esm.js +16 -5
  32. package/dist/numerics.min.umd.cjs +16 -5
  33. package/dist/numerics.umd.cjs +1349 -228
  34. package/dist/types/big-decimal/big-decimal.d.ts +1 -1
  35. package/dist/types/big-decimal/index.d.ts +1 -1
  36. package/dist/types/big-decimal/transcendentals.d.ts +1 -1
  37. package/dist/types/big-decimal/utils.d.ts +1 -1
  38. package/dist/types/common/ansi-codes.d.ts +1 -1
  39. package/dist/types/common/configuration-change.d.ts +1 -1
  40. package/dist/types/common/fuzzy-string-match.d.ts +1 -1
  41. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  42. package/dist/types/common/interruptible.d.ts +1 -1
  43. package/dist/types/common/one-of.d.ts +1 -1
  44. package/dist/types/common/signals.d.ts +1 -1
  45. package/dist/types/common/type/ast-nodes.d.ts +1 -1
  46. package/dist/types/common/type/boxed-type.d.ts +1 -1
  47. package/dist/types/common/type/lexer.d.ts +1 -1
  48. package/dist/types/common/type/parse.d.ts +1 -208
  49. package/dist/types/common/type/parser.d.ts +124 -2
  50. package/dist/types/common/type/primitive.d.ts +5 -1
  51. package/dist/types/common/type/reduce.d.ts +1 -1
  52. package/dist/types/common/type/serialize.d.ts +1 -1
  53. package/dist/types/common/type/subtype.d.ts +18 -1
  54. package/dist/types/common/type/type-builder.d.ts +1 -1
  55. package/dist/types/common/type/types.d.ts +1 -1
  56. package/dist/types/common/type/utils.d.ts +1 -1
  57. package/dist/types/common/utils.d.ts +1 -1
  58. package/dist/types/compile.d.ts +1 -1
  59. package/dist/types/compute-engine/assume.d.ts +13 -6
  60. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +1 -1
  61. package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
  62. package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
  63. package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
  64. package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
  65. package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
  66. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  67. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  68. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
  69. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
  70. package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +1 -1
  71. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  72. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  73. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +3 -3
  74. package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
  75. package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
  76. package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
  77. package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
  78. package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
  79. package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
  80. package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
  81. package/dist/types/compute-engine/boxed-expression/constraint-subject.d.ts +140 -0
  82. package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
  83. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  84. package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
  85. package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
  86. package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
  87. package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +14 -4
  88. package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
  89. package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
  90. package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
  91. package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
  92. package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
  93. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  94. package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
  95. package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
  96. package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
  97. package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
  98. package/dist/types/compute-engine/boxed-expression/rule-index.d.ts +112 -0
  99. package/dist/types/compute-engine/boxed-expression/rules.d.ts +2 -1
  100. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  101. package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
  102. package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
  103. package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
  104. package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
  105. package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
  106. package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
  107. package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
  108. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
  109. package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
  110. package/dist/types/compute-engine/collection-utils.d.ts +1 -1
  111. package/dist/types/compute-engine/compilation/base-compiler.d.ts +1 -1
  112. package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
  113. package/dist/types/compute-engine/compilation/constant-folding.d.ts +16 -1
  114. package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
  115. package/dist/types/compute-engine/compilation/gpu-target.d.ts +15 -5
  116. package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +4 -4
  117. package/dist/types/compute-engine/compilation/javascript-target.d.ts +1 -1
  118. package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
  119. package/dist/types/compute-engine/compilation/types.d.ts +1 -1
  120. package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
  121. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  122. package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
  123. package/dist/types/compute-engine/engine-cache.d.ts +1 -1
  124. package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
  125. package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
  126. package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
  127. package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
  128. package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
  129. package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
  130. package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
  131. package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
  132. package/dist/types/compute-engine/engine-runtime-state.d.ts +1 -1
  133. package/dist/types/compute-engine/engine-scope.d.ts +1 -1
  134. package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
  135. package/dist/types/compute-engine/engine-simplification-rules.d.ts +10 -2
  136. package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
  137. package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
  138. package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
  139. package/dist/types/compute-engine/free-functions.d.ts +1 -1
  140. package/dist/types/compute-engine/function-utils.d.ts +1 -1
  141. package/dist/types/compute-engine/fungrim/loader.d.ts +13 -0
  142. package/dist/types/compute-engine/fungrim/types.d.ts +160 -0
  143. package/dist/types/compute-engine/global-types.d.ts +1 -1
  144. package/dist/types/compute-engine/index.d.ts +48 -2
  145. package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
  146. package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
  147. package/dist/types/compute-engine/interval/elementary.d.ts +10 -2
  148. package/dist/types/compute-engine/interval/index.d.ts +2 -2
  149. package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
  150. package/dist/types/compute-engine/interval/types.d.ts +1 -1
  151. package/dist/types/compute-engine/interval/util.d.ts +1 -1
  152. package/dist/types/compute-engine/latex-syntax/dictionary/default-dictionary.d.ts +1 -1
  153. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  154. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  155. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  156. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-colors.d.ts +1 -1
  157. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  158. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  159. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
  160. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  161. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  162. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
  163. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  164. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  165. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  166. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  167. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
  168. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
  169. package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +4 -1
  170. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
  171. package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
  172. package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
  173. package/dist/types/compute-engine/latex-syntax/parse.d.ts +3 -2
  174. package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
  175. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -11
  176. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  177. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
  178. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  179. package/dist/types/compute-engine/latex-syntax/types.d.ts +1 -1
  180. package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
  181. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  182. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  183. package/dist/types/compute-engine/library/collections.d.ts +1 -1
  184. package/dist/types/compute-engine/library/colors.d.ts +1 -1
  185. package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
  186. package/dist/types/compute-engine/library/complex.d.ts +13 -1
  187. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  188. package/dist/types/compute-engine/library/core.d.ts +1 -1
  189. package/dist/types/compute-engine/library/fractals.d.ts +1 -1
  190. package/dist/types/compute-engine/library/library.d.ts +1 -1
  191. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  192. package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
  193. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  194. package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
  195. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  196. package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
  197. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  198. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  199. package/dist/types/compute-engine/library/sets.d.ts +27 -1
  200. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  201. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  202. package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
  203. package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
  204. package/dist/types/compute-engine/library/units.d.ts +1 -1
  205. package/dist/types/compute-engine/library/utils.d.ts +1 -1
  206. package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
  207. package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +7 -1
  208. package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
  209. package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
  210. package/dist/types/compute-engine/numerics/bernoulli.d.ts +39 -0
  211. package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
  212. package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
  213. package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
  214. package/dist/types/compute-engine/numerics/linear-algebra.d.ts +1 -1
  215. package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
  216. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  217. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  218. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +12 -1
  219. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  220. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  221. package/dist/types/compute-engine/numerics/random.d.ts +1 -1
  222. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  223. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  224. package/dist/types/compute-engine/numerics/special-functions.d.ts +78 -10
  225. package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
  226. package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
  227. package/dist/types/compute-engine/numerics/types.d.ts +1 -1
  228. package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
  229. package/dist/types/compute-engine/oeis.d.ts +1 -1
  230. package/dist/types/compute-engine/sequence.d.ts +1 -1
  231. package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
  232. package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
  233. package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
  234. package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
  235. package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
  236. package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
  237. package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
  238. package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
  239. package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
  240. package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
  241. package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
  242. package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
  243. package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
  244. package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
  245. package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
  246. package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
  247. package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
  248. package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
  249. package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
  250. package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
  251. package/dist/types/compute-engine/tensor/tensors.d.ts +3 -3
  252. package/dist/types/compute-engine/types-definitions.d.ts +1 -1
  253. package/dist/types/compute-engine/types-engine.d.ts +19 -3
  254. package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
  255. package/dist/types/compute-engine/types-expression.d.ts +17 -14
  256. package/dist/types/compute-engine/types-kernel-evaluation.d.ts +32 -1
  257. package/dist/types/compute-engine/types-kernel-serialization.d.ts +45 -3
  258. package/dist/types/compute-engine/types-serialization.d.ts +1 -1
  259. package/dist/types/compute-engine/types.d.ts +1 -1
  260. package/dist/types/compute-engine.d.ts +1 -1
  261. package/dist/types/core.d.ts +1 -1
  262. package/dist/types/identities.d.ts +3 -0
  263. package/dist/types/interval.d.ts +1 -1
  264. package/dist/types/latex-syntax.d.ts +2 -2
  265. package/dist/types/math-json/symbols.d.ts +1 -1
  266. package/dist/types/math-json/types.d.ts +1 -1
  267. package/dist/types/math-json/utils.d.ts +1 -1
  268. package/dist/types/math-json.d.ts +2 -2
  269. package/dist/types/numerics.d.ts +1 -1
  270. package/package.json +9 -3
@@ -1,4 +1,4 @@
1
- /** Compute Engine 0.58.0 */
1
+ /** Compute Engine 0.59.0 */
2
2
 
3
3
  // src/compute-engine/numerics/richardson.ts
4
4
  function extrapolate(f, x0, options = {}) {
@@ -159,6 +159,7 @@ function fpexp(x, scale) {
159
159
  return sum;
160
160
  }
161
161
  function fpln(x, scale) {
162
+ if (x <= 0n) throw new RangeError("fpln: input must be positive");
162
163
  if (x === scale) return 0n;
163
164
  const xNum = Number(x);
164
165
  const scaleNum = Number(scale);
@@ -808,9 +809,11 @@ var BigDecimal = class _BigDecimal {
808
809
  if (Number.isFinite(thisExp) && Number.isFinite(otherExp)) {
809
810
  if (other.significand === 0n) return _BigDecimal.NAN;
810
811
  if (this.significand === 0n) return fromRaw(0n, 0);
811
- return this.sub(this.div(other).trunc().mul(other)).toPrecision(
812
- _BigDecimal.precision
813
- );
812
+ const ediff = thisExp - otherExp;
813
+ const num = ediff >= 0 ? this.significand * pow10(ediff) : this.significand;
814
+ const den = ediff >= 0 ? other.significand : other.significand * pow10(-ediff);
815
+ const q = num / den;
816
+ return this.sub(fromRaw(q, 0).mul(other));
814
817
  }
815
818
  if (thisExp !== thisExp || otherExp !== otherExp) return _BigDecimal.NAN;
816
819
  if (!Number.isFinite(thisExp)) return _BigDecimal.NAN;
@@ -855,7 +858,10 @@ var BigDecimal = class _BigDecimal {
855
858
  return this.pow(n.neg()).inv();
856
859
  }
857
860
  const absSig = this.significand < 0n ? -this.significand : this.significand;
858
- const thisLog10 = bigintDigits(absSig) + this.exponent;
861
+ const sigDigits = bigintDigits(absSig);
862
+ const dropped = sigDigits > 15 ? sigDigits - 15 : 0;
863
+ const lead = dropped > 0 ? Number(absSig / 10n ** BigInt(dropped)) : Number(absSig);
864
+ const thisLog10 = Math.log10(lead) + dropped + this.exponent;
859
865
  const resultLog10 = Number(expValue) * thisLog10;
860
866
  if (resultLog10 > 9e15) {
861
867
  return this.significand < 0n && expValue % 2n !== 0n ? _BigDecimal.NEGATIVE_INFINITY : _BigDecimal.POSITIVE_INFINITY;
@@ -888,7 +894,19 @@ var BigDecimal = class _BigDecimal {
888
894
  return _BigDecimal.POSITIVE_INFINITY;
889
895
  }
890
896
  if (this.significand < 0n) return _BigDecimal.NAN;
891
- return n.mul(this.ln()).exp();
897
+ const baseSig = this.significand;
898
+ const decExpBase = this.exponent + bigintDigits(baseSig) - 1;
899
+ const nSig = n.significand < 0n ? -n.significand : n.significand;
900
+ const decExpN = n.exponent + bigintDigits(nSig) - 1;
901
+ const argMag = decExpN + Math.log10(Math.abs(decExpBase) * 2.303 + 3) + 1;
902
+ const extra = Math.min(20, Math.max(2, Math.ceil(argMag) + 2));
903
+ const savedPrec = _BigDecimal.precision;
904
+ _BigDecimal.precision = savedPrec + extra;
905
+ try {
906
+ return n.mul(this.ln()).exp().toPrecision(savedPrec);
907
+ } finally {
908
+ _BigDecimal.precision = savedPrec;
909
+ }
892
910
  }
893
911
  // ---------- Conversion methods ----------
894
912
  /** Convert to a JavaScript number. May lose precision for large values. */
@@ -1129,6 +1147,20 @@ function fromFixedPoint(fp, scale, targetPrecision) {
1129
1147
  const sig = negative ? -absFp : absFp;
1130
1148
  return fromRaw(sig, resultExp);
1131
1149
  }
1150
+ function decimalExponent(x) {
1151
+ const sig = x.significand < 0n ? -x.significand : x.significand;
1152
+ return x.exponent + bigintDigits(sig) - 1;
1153
+ }
1154
+ var MAX_SAFE_EXPONENT = BigInt(Number.MAX_SAFE_INTEGER);
1155
+ var _ln10Fp = null;
1156
+ var _ln10Scale = null;
1157
+ function ln10Fixed(scale) {
1158
+ if (_ln10Scale !== scale) {
1159
+ _ln10Fp = fpln(10n * scale, scale);
1160
+ _ln10Scale = scale;
1161
+ }
1162
+ return _ln10Fp;
1163
+ }
1132
1164
  BigDecimal.prototype.sqrt = function() {
1133
1165
  if (this.isNaN()) return BigDecimal.NAN;
1134
1166
  if (this.isZero()) return BigDecimal.ZERO;
@@ -1139,9 +1171,13 @@ BigDecimal.prototype.sqrt = function() {
1139
1171
  if (this.significand < 0n) return BigDecimal.NAN;
1140
1172
  const targetPrec = BigDecimal.precision;
1141
1173
  const workingPrec = targetPrec + 10;
1142
- const [fp, scale] = toFixedPoint(this, workingPrec);
1174
+ const e = decimalExponent(this);
1175
+ const k = Math.floor(e / 2);
1176
+ const m = fromRaw(this.significand, this.exponent - 2 * k);
1177
+ const [fp, scale] = toFixedPoint(m, workingPrec);
1143
1178
  const sqrtFp = fpsqrt(fp, scale);
1144
- return fromFixedPoint(sqrtFp, scale, targetPrec);
1179
+ const root = fromFixedPoint(sqrtFp, scale, targetPrec);
1180
+ return fromRaw(root.significand, root.exponent + k);
1145
1181
  };
1146
1182
  BigDecimal.prototype.cbrt = function() {
1147
1183
  if (this.isNaN()) return BigDecimal.NAN;
@@ -1155,10 +1191,13 @@ BigDecimal.prototype.cbrt = function() {
1155
1191
  }
1156
1192
  const targetPrec = BigDecimal.precision;
1157
1193
  const workingPrec = targetPrec + 10;
1158
- const [fp, scale] = toFixedPoint(this, workingPrec);
1194
+ const e = decimalExponent(this);
1195
+ const k = Math.floor(e / 3);
1196
+ const m = fromRaw(this.significand, this.exponent - 3 * k);
1197
+ const [fp, scale] = toFixedPoint(m, workingPrec);
1159
1198
  const C = fp * scale * scale;
1160
1199
  let x;
1161
- const numVal = this.toNumber();
1200
+ const numVal = m.toNumber();
1162
1201
  const scaleNum = Number(scale);
1163
1202
  if (Number.isFinite(numVal) && numVal > 0 && Number.isFinite(scaleNum)) {
1164
1203
  const approx = Math.cbrt(numVal);
@@ -1187,7 +1226,8 @@ BigDecimal.prototype.cbrt = function() {
1187
1226
  const diffNext = bigintAbs(next * next * next - C);
1188
1227
  if (diffNext < diffX) x = next;
1189
1228
  }
1190
- return fromFixedPoint(x, scale, targetPrec);
1229
+ const root = fromFixedPoint(x, scale, targetPrec);
1230
+ return fromRaw(root.significand, root.exponent + k);
1191
1231
  };
1192
1232
  BigDecimal.sqrt = function(x) {
1193
1233
  return x.sqrt();
@@ -1202,11 +1242,27 @@ BigDecimal.prototype.exp = function() {
1202
1242
  return BigDecimal.ZERO;
1203
1243
  }
1204
1244
  if (this.isZero()) return BigDecimal.ONE;
1245
+ if (decimalExponent(this) >= 17)
1246
+ return this.significand > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
1205
1247
  const targetPrec = BigDecimal.precision;
1206
- const workingPrec = targetPrec + 15;
1207
- const [fp, scale] = toFixedPoint(this, workingPrec);
1208
- const expFp = fpexp(fp, scale);
1209
- return fromFixedPoint(expFp, scale, targetPrec);
1248
+ const absSig = this.significand < 0n ? -this.significand : this.significand;
1249
+ const magnitude = Math.max(0, this.exponent + bigintDigits(absSig));
1250
+ const workingPrec = targetPrec + 20 + magnitude;
1251
+ const [xFp, scale] = toFixedPoint(this, workingPrec);
1252
+ const l10 = ln10Fixed(scale);
1253
+ let k = xFp / l10;
1254
+ let rFp = xFp - k * l10;
1255
+ if (rFp < 0n) {
1256
+ k -= 1n;
1257
+ rFp += l10;
1258
+ }
1259
+ if (k > MAX_SAFE_EXPONENT || k < -MAX_SAFE_EXPONENT)
1260
+ return k > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
1261
+ const expR = fromFixedPoint(fpexp(rFp, scale), scale, targetPrec);
1262
+ const newExp = expR.exponent + Number(k);
1263
+ if (!Number.isSafeInteger(newExp))
1264
+ return k > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
1265
+ return fromRaw(expR.significand, newExp);
1210
1266
  };
1211
1267
  BigDecimal.prototype.ln = function() {
1212
1268
  if (this.isNaN()) return BigDecimal.NAN;
@@ -1218,10 +1274,16 @@ BigDecimal.prototype.ln = function() {
1218
1274
  if (this.significand < 0n) return BigDecimal.NAN;
1219
1275
  if (this.eq(1)) return BigDecimal.ZERO;
1220
1276
  const targetPrec = BigDecimal.precision;
1221
- const workingPrec = targetPrec + 15;
1222
- const [fp, scale] = toFixedPoint(this, workingPrec);
1223
- const lnFp = fpln(fp, scale);
1224
- return fromFixedPoint(lnFp, scale, targetPrec);
1277
+ const sig = this.significand;
1278
+ const digits = bigintDigits(sig);
1279
+ const e = this.exponent + digits - 1;
1280
+ const m = fromRaw(sig, -(digits - 1));
1281
+ const eDigits = Math.abs(e).toString().length;
1282
+ const workingPrec = targetPrec + 20 + eDigits;
1283
+ const [mFp, scale] = toFixedPoint(m, workingPrec);
1284
+ const l10 = ln10Fixed(scale);
1285
+ const resultFp = fpln(mFp, scale) + BigInt(e) * l10;
1286
+ return fromFixedPoint(resultFp, scale, targetPrec);
1225
1287
  };
1226
1288
  BigDecimal.prototype.log = function(base) {
1227
1289
  const b = base instanceof BigDecimal ? base : new BigDecimal(base);
@@ -1241,7 +1303,10 @@ BigDecimal.prototype.sin = function() {
1241
1303
  if (!this.isFinite()) return BigDecimal.NAN;
1242
1304
  if (this.isZero()) return BigDecimal.ZERO;
1243
1305
  const targetPrec = BigDecimal.precision;
1244
- const workingPrec = targetPrec + 15;
1306
+ const e = decimalExponent(this);
1307
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1308
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
1309
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
1245
1310
  const [fp, scale] = toFixedPoint(this, workingPrec);
1246
1311
  const [sinFp] = fpsincos(fp, scale);
1247
1312
  return fromFixedPoint(sinFp, scale, targetPrec);
@@ -1252,6 +1317,8 @@ BigDecimal.prototype.cos = function() {
1252
1317
  if (this.isZero()) return BigDecimal.ONE;
1253
1318
  const targetPrec = BigDecimal.precision;
1254
1319
  const workingPrec = targetPrec + 15;
1320
+ const e = decimalExponent(this);
1321
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
1255
1322
  const [fp, scale] = toFixedPoint(this, workingPrec);
1256
1323
  const [, cosFp] = fpsincos(fp, scale);
1257
1324
  return fromFixedPoint(cosFp, scale, targetPrec);
@@ -1261,7 +1328,10 @@ BigDecimal.prototype.tan = function() {
1261
1328
  if (!this.isFinite()) return BigDecimal.NAN;
1262
1329
  if (this.isZero()) return BigDecimal.ZERO;
1263
1330
  const targetPrec = BigDecimal.precision;
1264
- const workingPrec = targetPrec + 15;
1331
+ const e = decimalExponent(this);
1332
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1333
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
1334
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
1265
1335
  const [fp, scale] = toFixedPoint(this, workingPrec);
1266
1336
  const [sinFp, cosFp] = fpsincos(fp, scale);
1267
1337
  if (cosFp === 0n) {
@@ -1279,7 +1349,9 @@ BigDecimal.prototype.atan = function() {
1279
1349
  return piHalf.neg();
1280
1350
  }
1281
1351
  const targetPrec = BigDecimal.precision;
1282
- const workingPrec = targetPrec + 15;
1352
+ const e = decimalExponent(this);
1353
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1354
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
1283
1355
  const [fp, scale] = toFixedPoint(this, workingPrec);
1284
1356
  const atanFp = fpatan(fp, scale);
1285
1357
  return fromFixedPoint(atanFp, scale, targetPrec);
@@ -1296,7 +1368,9 @@ BigDecimal.prototype.asin = function() {
1296
1368
  return this.significand > 0n ? piHalf : piHalf.neg();
1297
1369
  }
1298
1370
  const targetPrec = BigDecimal.precision;
1299
- const workingPrec = targetPrec + 20;
1371
+ const e = decimalExponent(this);
1372
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1373
+ const workingPrec = targetPrec + 20 + (e < 0 ? -e : 0);
1300
1374
  const [xFp, scale] = toFixedPoint(this, workingPrec);
1301
1375
  const x2 = fpmul(xFp, xFp, scale);
1302
1376
  const oneMinusX2 = scale - x2;
@@ -1359,6 +1433,23 @@ BigDecimal.prototype.sinh = function() {
1359
1433
  if (this.significand > 0n) return BigDecimal.POSITIVE_INFINITY;
1360
1434
  return BigDecimal.NEGATIVE_INFINITY;
1361
1435
  }
1436
+ const targetPrec = BigDecimal.precision;
1437
+ const e = decimalExponent(this);
1438
+ if (e < 0) {
1439
+ if (-2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1440
+ const saved = BigDecimal.precision;
1441
+ BigDecimal.precision = targetPrec - e + 5;
1442
+ try {
1443
+ const expX2 = this.exp();
1444
+ return expX2.sub(expX2.inv()).div(BigDecimal.TWO).toPrecision(targetPrec);
1445
+ } finally {
1446
+ BigDecimal.precision = saved;
1447
+ }
1448
+ }
1449
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3)) {
1450
+ const h = this.abs().exp().div(BigDecimal.TWO);
1451
+ return this.significand > 0n ? h : h.neg();
1452
+ }
1362
1453
  const expX = this.exp();
1363
1454
  const expNegX = expX.inv();
1364
1455
  return expX.sub(expNegX).div(BigDecimal.TWO);
@@ -1369,6 +1460,9 @@ BigDecimal.prototype.cosh = function() {
1369
1460
  if (!this.isFinite()) {
1370
1461
  return BigDecimal.POSITIVE_INFINITY;
1371
1462
  }
1463
+ const targetPrec = BigDecimal.precision;
1464
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3))
1465
+ return this.abs().exp().div(BigDecimal.TWO);
1372
1466
  const expX = this.exp();
1373
1467
  const expNegX = expX.inv();
1374
1468
  return expX.add(expNegX).div(BigDecimal.TWO);
@@ -1380,6 +1474,21 @@ BigDecimal.prototype.tanh = function() {
1380
1474
  if (this.significand > 0n) return BigDecimal.ONE;
1381
1475
  return BigDecimal.NEGATIVE_ONE;
1382
1476
  }
1477
+ const targetPrec = BigDecimal.precision;
1478
+ const e = decimalExponent(this);
1479
+ if (e < 0) {
1480
+ if (-2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1481
+ const saved = BigDecimal.precision;
1482
+ BigDecimal.precision = targetPrec - e + 5;
1483
+ try {
1484
+ const exp2x2 = this.mul(BigDecimal.TWO).exp();
1485
+ return exp2x2.sub(BigDecimal.ONE).div(exp2x2.add(BigDecimal.ONE)).toPrecision(targetPrec);
1486
+ } finally {
1487
+ BigDecimal.precision = saved;
1488
+ }
1489
+ }
1490
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3))
1491
+ return this.significand > 0n ? BigDecimal.ONE : BigDecimal.NEGATIVE_ONE;
1383
1492
  const exp2x = this.mul(BigDecimal.TWO).exp();
1384
1493
  return exp2x.sub(BigDecimal.ONE).div(exp2x.add(BigDecimal.ONE));
1385
1494
  };
@@ -1428,6 +1537,7 @@ var MACHINE_PRECISION = Math.floor(
1428
1537
  Math.log10(Math.pow(2, MACHINE_PRECISION_BITS))
1429
1538
  );
1430
1539
  var DEFAULT_TOLERANCE = 1e-10;
1540
+ var SMALL_INTEGER = 1e6;
1431
1541
  var MAX_ITERATION = 1e4;
1432
1542
  function gcd(a, b) {
1433
1543
  if (a === 0) return b;
@@ -1439,7 +1549,8 @@ function gcd(a, b) {
1439
1549
  }
1440
1550
  function lcm(a, b) {
1441
1551
  if (a === 0 || b === 0) return 0;
1442
- const res = BigInt(a) * BigInt(b) / BigInt(gcd(a, b));
1552
+ let res = BigInt(a) * BigInt(b) / BigInt(gcd(a, b));
1553
+ if (res < 0n) res = -res;
1443
1554
  return Number(res);
1444
1555
  }
1445
1556
  function factorial(n) {
@@ -1529,216 +1640,27 @@ var PRIMITIVE_TYPES = [
1529
1640
  "error",
1530
1641
  ...EXPRESSION_TYPES
1531
1642
  ];
1643
+ var NUMERIC_TYPES_SET = new Set(
1644
+ NUMERIC_TYPES
1645
+ );
1646
+ var COLLECTION_TYPES_SET = new Set(
1647
+ COLLECTION_TYPES
1648
+ );
1649
+ var SCALAR_TYPES_SET = new Set(
1650
+ SCALAR_TYPES
1651
+ );
1652
+ var PRIMITIVE_TYPES_SET = new Set(
1653
+ PRIMITIVE_TYPES
1654
+ );
1655
+ function isValidPrimitiveType(s) {
1656
+ if (typeof s !== "string") return false;
1657
+ return PRIMITIVE_TYPES_SET.has(s);
1658
+ }
1532
1659
  function isValidType(t) {
1533
- if (typeof t === "string")
1534
- return PRIMITIVE_TYPES.includes(t);
1660
+ if (typeof t === "string") return PRIMITIVE_TYPES_SET.has(t);
1535
1661
  if (typeof t !== "object") return false;
1536
1662
  if (!("kind" in t)) return false;
1537
- return t.kind === "signature" || t.kind === "union" || t.kind === "intersection" || t.kind === "negation" || t.kind === "tuple" || t.kind === "list" || t.kind === "record" || t.kind === "dictionary" || t.kind === "set" || t.kind === "function" || t.kind === "collection" || t.kind === "indexed_collection" || t.kind === "reference";
1538
- }
1539
-
1540
- // src/common/type/serialize.ts
1541
- var NEGATION_PRECEDENCE = 3;
1542
- var UNION_PRECEDENCE = 1;
1543
- var INTERSECTION_PRECEDENCE = 2;
1544
- var LIST_PRECEDENCE = 4;
1545
- var RECORD_PRECEDENCE = 5;
1546
- var DICTIONARY_PRECEDENCE = 6;
1547
- var SET_PRECEDENCE = 7;
1548
- var COLLECTION_PRECEDENCE = 8;
1549
- var TUPLE_PRECEDENCE = 9;
1550
- var SIGNATURE_PRECEDENCE = 10;
1551
- var VALUE_PRECEDENCE = 11;
1552
- function typeToString(type, precedence = 0) {
1553
- if (typeof type === "string") return type;
1554
- let result = "";
1555
- switch (type.kind) {
1556
- case "value":
1557
- if (typeof type.value === "string") result = `"${type.value}"`;
1558
- else if (typeof type.value === "boolean")
1559
- result = type.value ? "true" : "false";
1560
- else result = type.value.toString();
1561
- break;
1562
- case "reference":
1563
- result = type.name;
1564
- break;
1565
- case "negation":
1566
- result = `!${typeToString(type.type, NEGATION_PRECEDENCE)}`;
1567
- break;
1568
- case "union":
1569
- result = type.types.map((t) => typeToString(t, UNION_PRECEDENCE)).join(" | ");
1570
- break;
1571
- case "intersection":
1572
- result = type.types.map((t) => typeToString(t, INTERSECTION_PRECEDENCE)).join(" & ");
1573
- break;
1574
- case "expression":
1575
- result = `expression<${symbolName(type.operator)}>`;
1576
- break;
1577
- case "symbol":
1578
- result = `symbol<${symbolName(type.name)}>`;
1579
- break;
1580
- case "numeric":
1581
- if (Number.isFinite(type.lower) && Number.isFinite(type.upper)) {
1582
- result = `${type.type}<${type.lower}..${type.upper}>`;
1583
- } else if (Number.isFinite(type.lower)) {
1584
- result = `${type.type}<${type.lower}..>`;
1585
- } else if (Number.isFinite(type.upper)) {
1586
- result = `${type.type}<..${type.upper}>`;
1587
- } else {
1588
- result = `${type.type}`;
1589
- }
1590
- break;
1591
- case "list":
1592
- if (type.dimensions && typeof type.elements === "string" && NUMERIC_TYPES.includes(type.elements)) {
1593
- if (type.dimensions === void 0) {
1594
- if (type.elements === "number") result = "tensor";
1595
- } else if (type.dimensions.length === 1) {
1596
- if (type.elements === "number") {
1597
- if (type.dimensions[0] < 0) result = "vector";
1598
- else result = `vector<${type.dimensions[0]}>`;
1599
- } else {
1600
- if (type.dimensions[0] < 0)
1601
- result = `vector<${typeToString(type.elements)}>`;
1602
- else
1603
- result = `vector<${typeToString(type.elements)}^${type.dimensions[0]}>`;
1604
- }
1605
- } else if (type.dimensions.length === 2) {
1606
- const dims = type.dimensions;
1607
- if (type.elements === "number") {
1608
- if (dims[0] < 0 && dims[1] < 0) result = "matrix";
1609
- else result = `matrix<${dims[0]}x${dims[1]}>`;
1610
- } else {
1611
- if (dims[0] < 0 && dims[1] < 0)
1612
- result = `matrix<${typeToString(type.elements)}>`;
1613
- else
1614
- result = `matrix<${typeToString(type.elements)}^(${dims[0]}x${dims[1]})>`;
1615
- }
1616
- }
1617
- }
1618
- if (!result) {
1619
- const dimensions = type.dimensions ? type.dimensions.length === 1 ? `^${type.dimensions[0].toString()}` : `^(${type.dimensions.join("x")})` : "";
1620
- result = `list<${typeToString(type.elements)}${dimensions}>`;
1621
- }
1622
- break;
1623
- case "record":
1624
- const elements = Object.entries(type.elements).map(([key, value]) => `${key}: ${typeToString(value)}`).join(", ");
1625
- result = `record<${elements}>`;
1626
- break;
1627
- case "dictionary":
1628
- result = `dictionary<${typeToString(type.values)}>`;
1629
- break;
1630
- case "set":
1631
- result = `set<${typeToString(type.elements)}>`;
1632
- break;
1633
- case "collection":
1634
- result = `collection<${typeToString(type.elements)}>`;
1635
- break;
1636
- case "indexed_collection":
1637
- result = `indexed_collection<${typeToString(type.elements)}>`;
1638
- break;
1639
- case "tuple":
1640
- if (type.elements.length === 0) result = "tuple";
1641
- else if (type.elements.length === 1) {
1642
- const [el] = type.elements;
1643
- result = `tuple<${namedElement(el)}>`;
1644
- } else {
1645
- result = "tuple<" + type.elements.map((el) => namedElement(el)).join(", ") + ">";
1646
- }
1647
- break;
1648
- case "signature":
1649
- const args = type.args ? type.args.map((arg) => namedElement(arg)).join(", ") : "";
1650
- const optArgs = type.optArgs ? type.optArgs.map((arg) => namedElement(arg) + "?").join(", ") : "";
1651
- const varArg = type.variadicArg ? type.variadicMin === 0 ? `${namedElement(type.variadicArg)}*` : `${namedElement(type.variadicArg)}+` : "";
1652
- const argsList = [args, optArgs, varArg].filter((s) => s).join(", ");
1653
- result = `(${argsList}) -> ${typeToString(type.result)}`;
1654
- break;
1655
- default:
1656
- result = "error";
1657
- }
1658
- if (precedence > 0 && precedence > getPrecedence(type.kind))
1659
- return `(${result})`;
1660
- return result;
1661
- }
1662
- function namedElement(el) {
1663
- if (el.name) return `${el.name}: ${typeToString(el.type)}`;
1664
- return typeToString(el.type);
1665
- }
1666
- function symbolName(name) {
1667
- if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) return name;
1668
- return `\`${name}\``;
1669
- }
1670
- function getPrecedence(kind) {
1671
- switch (kind) {
1672
- case "negation":
1673
- return NEGATION_PRECEDENCE;
1674
- case "union":
1675
- return UNION_PRECEDENCE;
1676
- case "intersection":
1677
- return INTERSECTION_PRECEDENCE;
1678
- case "list":
1679
- return LIST_PRECEDENCE;
1680
- case "record":
1681
- return RECORD_PRECEDENCE;
1682
- case "dictionary":
1683
- return DICTIONARY_PRECEDENCE;
1684
- case "set":
1685
- return SET_PRECEDENCE;
1686
- case "collection":
1687
- case "indexed_collection":
1688
- return COLLECTION_PRECEDENCE;
1689
- case "tuple":
1690
- return TUPLE_PRECEDENCE;
1691
- case "signature":
1692
- return SIGNATURE_PRECEDENCE;
1693
- case "value":
1694
- return VALUE_PRECEDENCE;
1695
- default:
1696
- return 0;
1697
- }
1698
- }
1699
-
1700
- // src/common/fuzzy-string-match.ts
1701
- function levenshtein(source, target) {
1702
- if (source === target) return 0;
1703
- if (source.length === 0) return target.length;
1704
- if (target.length === 0) return source.length;
1705
- let prevRow = Array.from(
1706
- { length: source.length + 1 },
1707
- (_, j) => j
1708
- );
1709
- let currRow = new Array(source.length + 1);
1710
- for (let i = 1; i <= target.length; i++) {
1711
- currRow[0] = i;
1712
- for (let j = 1; j <= source.length; j++) {
1713
- const cost = source[j - 1] === target[i - 1] ? 0 : 1;
1714
- currRow[j] = Math.min(
1715
- prevRow[j] + 1,
1716
- // deletion
1717
- currRow[j - 1] + 1,
1718
- // insertion
1719
- prevRow[j - 1] + cost
1720
- // substitution
1721
- );
1722
- }
1723
- [prevRow, currRow] = [currRow, prevRow];
1724
- }
1725
- return prevRow[source.length];
1726
- }
1727
- function fuzzyStringMatch(invalidWord, validWords) {
1728
- const threshold = 7;
1729
- let bestMatch = null;
1730
- let minDistance = Infinity;
1731
- const invalidLength = invalidWord.length;
1732
- for (const word of validWords) {
1733
- if (Math.abs(invalidLength - word.length) > threshold) continue;
1734
- const distance = levenshtein(invalidWord, word);
1735
- if (distance === 0) return word;
1736
- if (distance <= threshold && distance < minDistance) {
1737
- minDistance = distance;
1738
- bestMatch = word;
1739
- }
1740
- }
1741
- return bestMatch;
1663
+ return t.kind === "signature" || t.kind === "union" || t.kind === "intersection" || t.kind === "negation" || t.kind === "value" || t.kind === "tuple" || t.kind === "list" || t.kind === "record" || t.kind === "dictionary" || t.kind === "set" || t.kind === "symbol" || t.kind === "expression" || t.kind === "numeric" || t.kind === "collection" || t.kind === "indexed_collection" || t.kind === "reference";
1742
1664
  }
1743
1665
 
1744
1666
  // src/common/type/lexer.ts
@@ -2448,19 +2370,13 @@ var Parser = class {
2448
2370
  );
2449
2371
  let dimensions;
2450
2372
  if (this.match("<")) {
2451
- dimensions = this.parseDimensionWithX();
2452
- if (!dimensions) {
2453
- dimensions = this.parseDimensions();
2454
- }
2373
+ dimensions = this.parseDimensions();
2455
2374
  if (!dimensions) {
2456
2375
  const type = this.parseUnionType();
2457
2376
  if (type) {
2458
2377
  elementType = type;
2459
2378
  if (this.match("^")) {
2460
- dimensions = this.parseDimensionWithX();
2461
- if (!dimensions) {
2462
- dimensions = this.parseDimensions();
2463
- }
2379
+ dimensions = this.parseCaretDimensions();
2464
2380
  }
2465
2381
  }
2466
2382
  }
@@ -2501,19 +2417,13 @@ var Parser = class {
2501
2417
  );
2502
2418
  let dimensions;
2503
2419
  if (this.match("<")) {
2504
- dimensions = this.parseDimensionWithX();
2505
- if (!dimensions) {
2506
- dimensions = this.parseDimensions();
2507
- }
2420
+ dimensions = this.parseDimensions();
2508
2421
  if (!dimensions) {
2509
2422
  const type = this.parseUnionType();
2510
2423
  if (type) {
2511
2424
  elementType = type;
2512
2425
  if (this.match("^")) {
2513
- dimensions = this.parseDimensionWithX();
2514
- if (!dimensions) {
2515
- dimensions = this.parseDimensions();
2516
- }
2426
+ dimensions = this.parseCaretDimensions();
2517
2427
  }
2518
2428
  }
2519
2429
  }
@@ -2544,16 +2454,30 @@ var Parser = class {
2544
2454
  return this.createNode("tensor", { elementType });
2545
2455
  }
2546
2456
  parseDimensions() {
2547
- const dimensions = [];
2548
2457
  const firstDim = this.parseDimension();
2549
2458
  if (!firstDim) return void 0;
2550
- dimensions.push(firstDim);
2551
- while (this.match("x")) {
2552
- const dim = this.parseDimension();
2553
- if (!dim) {
2554
- this.error("Expected dimension after x");
2459
+ const dimensions = [firstDim];
2460
+ for (; ; ) {
2461
+ const tok = this.current;
2462
+ if (tok.type === "IDENTIFIER" && /^(x\d+)+$/.test(tok.value)) {
2463
+ this.advance();
2464
+ for (const m of tok.value.match(/x(\d+)/g))
2465
+ dimensions.push(
2466
+ this.createNode("dimension", {
2467
+ size: parseInt(m.slice(1))
2468
+ })
2469
+ );
2470
+ } else if (tok.type === "IDENTIFIER" && tok.value === "x") {
2471
+ const next = this.lexer.peekToken();
2472
+ if (next.type !== "NUMBER_LITERAL" && next.type !== "?")
2473
+ this.error(
2474
+ "Expected a positive integer literal or `?` after x. For example: `2x3` or `2x?`"
2475
+ );
2476
+ this.advance();
2477
+ dimensions.push(this.parseDimension());
2478
+ } else {
2479
+ break;
2555
2480
  }
2556
- dimensions.push(dim);
2557
2481
  }
2558
2482
  return dimensions;
2559
2483
  }
@@ -2567,35 +2491,11 @@ var Parser = class {
2567
2491
  }
2568
2492
  return void 0;
2569
2493
  }
2570
- parseDimensionWithX() {
2571
- if (this.current.type === "NUMBER_LITERAL") {
2572
- const dimensions = [];
2573
- const firstDim = parseInt(this.advance().value);
2574
- dimensions.push(
2575
- this.createNode("dimension", { size: firstDim })
2576
- );
2577
- if (this.current.type === "IDENTIFIER" && this.current.value.startsWith("x")) {
2578
- const dimString = this.current.value;
2579
- const matches = dimString.match(/x(\d+)/g);
2580
- if (matches && matches.join("") === dimString) {
2581
- this.advance();
2582
- for (const match of matches) {
2583
- const dimValue = parseInt(match.substring(1));
2584
- dimensions.push(
2585
- this.createNode("dimension", { size: dimValue })
2586
- );
2587
- }
2588
- } else if (dimString === "x" || dimString.startsWith("x")) {
2589
- this.error(
2590
- "Expected a positive integer literal or `?` after x. For example: `2x3` or `2x?`"
2591
- );
2592
- }
2593
- }
2594
- if (dimensions.length > 1) {
2595
- return dimensions;
2596
- }
2597
- }
2598
- return void 0;
2494
+ parseCaretDimensions() {
2495
+ const paren = this.match("(");
2496
+ const dimensions = this.parseDimensions();
2497
+ if (paren) this.expect(")");
2498
+ return dimensions;
2599
2499
  }
2600
2500
  parseTupleType() {
2601
2501
  if (this.current.type === "IDENTIFIER" && this.current.value === "tuple") {
@@ -2780,6 +2680,18 @@ var Parser = class {
2780
2680
  this.expect("..");
2781
2681
  const upperBound = this.parseValue();
2782
2682
  this.expect(">");
2683
+ const lower = lowerBound?.value ?? -Infinity;
2684
+ const upper = upperBound?.value ?? Infinity;
2685
+ if (Number.isNaN(lower) || Number.isNaN(upper))
2686
+ this.error(
2687
+ "Invalid numeric type",
2688
+ "Lower and upper bounds must be valid numbers"
2689
+ );
2690
+ if (lower > upper)
2691
+ this.error(
2692
+ `Invalid range: ${lower}..${upper}`,
2693
+ "The lower bound must be less than the upper bound"
2694
+ );
2783
2695
  return this.createNode("numeric", {
2784
2696
  baseType,
2785
2697
  lowerBound,
@@ -2794,7 +2706,7 @@ var Parser = class {
2794
2706
  parsePrimitiveType() {
2795
2707
  if (this.current.type === "IDENTIFIER") {
2796
2708
  const name = this.current.value;
2797
- if (PRIMITIVE_TYPES.includes(name)) {
2709
+ if (PRIMITIVE_TYPES_SET.has(name)) {
2798
2710
  this.advance();
2799
2711
  return this.createNode("primitive", { name });
2800
2712
  }
@@ -3128,14 +3040,32 @@ function buildTypeFromAST(node, typeResolver) {
3128
3040
  }
3129
3041
 
3130
3042
  // src/common/type/parse.ts
3043
+ var TYPE_CACHE = /* @__PURE__ */ new Map();
3044
+ var TYPE_CACHE_MAX_SIZE = 2048;
3045
+ function deepFreeze(obj) {
3046
+ if (obj === null || typeof obj !== "object") return obj;
3047
+ if (Object.isFrozen(obj)) return obj;
3048
+ Object.freeze(obj);
3049
+ for (const value of Object.values(obj)) deepFreeze(value);
3050
+ return obj;
3051
+ }
3131
3052
  function parseType(s, typeResolver) {
3132
3053
  if (s === void 0) return void 0;
3133
3054
  if (isValidType(s)) return s;
3134
3055
  if (typeof s !== "string") return void 0;
3056
+ const cacheable = typeResolver === void 0;
3057
+ if (cacheable) {
3058
+ const cached = TYPE_CACHE.get(s);
3059
+ if (cached !== void 0) return cached;
3060
+ }
3135
3061
  try {
3136
3062
  const parser = new Parser(s, { typeResolver });
3137
3063
  const ast = parser.parseType();
3138
3064
  const type = buildTypeFromAST(ast, typeResolver);
3065
+ if (cacheable) {
3066
+ if (TYPE_CACHE.size >= TYPE_CACHE_MAX_SIZE) TYPE_CACHE.clear();
3067
+ TYPE_CACHE.set(s, deepFreeze(type));
3068
+ }
3139
3069
  return type;
3140
3070
  } catch (error) {
3141
3071
  throw new Error(
@@ -3210,19 +3140,54 @@ var PRIMITIVE_SUBTYPES = {
3210
3140
  color: [],
3211
3141
  expression: EXPRESSION_TYPES
3212
3142
  };
3143
+ var PRIMITIVE_SUBTYPES_CLOSURE = (() => {
3144
+ const closure = {};
3145
+ const closeOver = (t) => {
3146
+ if (closure[t]) return closure[t];
3147
+ const result = /* @__PURE__ */ new Set([t]);
3148
+ closure[t] = result;
3149
+ for (const sub2 of PRIMITIVE_SUBTYPES[t]) {
3150
+ if (sub2 === t) continue;
3151
+ for (const s of closeOver(sub2)) result.add(s);
3152
+ }
3153
+ return result;
3154
+ };
3155
+ for (const t of Object.keys(PRIMITIVE_SUBTYPES))
3156
+ closeOver(t);
3157
+ return closure;
3158
+ })();
3213
3159
  function isPrimitiveSubtype(lhs, rhs) {
3214
3160
  if (rhs === "any") return true;
3215
3161
  if (lhs === "never") return true;
3216
3162
  if (lhs === "unknown" || rhs === "unknown") return false;
3217
3163
  if (lhs === rhs) return true;
3218
- return PRIMITIVE_SUBTYPES[rhs].includes(lhs);
3164
+ return PRIMITIVE_SUBTYPES_CLOSURE[rhs].has(lhs);
3165
+ }
3166
+ function meetPrimitiveTypes(a, b) {
3167
+ if (a === b) return [a];
3168
+ const sa = PRIMITIVE_SUBTYPES_CLOSURE[a];
3169
+ const sb = PRIMITIVE_SUBTYPES_CLOSURE[b];
3170
+ if (sa.has(b)) return [b];
3171
+ if (sb.has(a)) return [a];
3172
+ const key = a < b ? `${a}|${b}` : `${b}|${a}`;
3173
+ const cached = MEET_CACHE.get(key);
3174
+ if (cached) return cached;
3175
+ const common = [];
3176
+ for (const t of sa) if (sb.has(t)) common.push(t);
3177
+ const maximals = common.filter(
3178
+ (t) => !common.some((u) => u !== t && PRIMITIVE_SUBTYPES_CLOSURE[u].has(t))
3179
+ );
3180
+ MEET_CACHE.set(key, maximals);
3181
+ return maximals;
3219
3182
  }
3183
+ var MEET_CACHE = /* @__PURE__ */ new Map();
3220
3184
  function isSubtype(lhs, rhs) {
3221
- if (typeof lhs === "string" && !PRIMITIVE_TYPES.includes(lhs))
3185
+ if (typeof lhs === "string" && !PRIMITIVE_TYPES_SET.has(lhs))
3222
3186
  lhs = parseType(lhs);
3223
- if (typeof rhs === "string" && !PRIMITIVE_TYPES.includes(rhs))
3187
+ if (typeof rhs === "string" && !PRIMITIVE_TYPES_SET.has(rhs))
3224
3188
  rhs = parseType(rhs);
3225
3189
  if (rhs === "any") return true;
3190
+ if (lhs === "never") return true;
3226
3191
  if (rhs === "never") return false;
3227
3192
  if (rhs === "error") return lhs === "error";
3228
3193
  if (rhs === "nothing") return lhs === "nothing";
@@ -3237,7 +3202,7 @@ function isSubtype(lhs, rhs) {
3237
3202
  if (typeof lhs.value === "number") {
3238
3203
  if (Number.isInteger(lhs.value))
3239
3204
  return isPrimitiveSubtype("integer", rhs);
3240
- return isPrimitiveSubtype("number", rhs);
3205
+ return isPrimitiveSubtype("real", rhs);
3241
3206
  }
3242
3207
  if (typeof lhs.value === "boolean")
3243
3208
  return isPrimitiveSubtype("boolean", rhs);
@@ -3467,7 +3432,7 @@ function isSubtype(lhs, rhs) {
3467
3432
  }
3468
3433
  function isNumeric(type) {
3469
3434
  if (typeof type === "string")
3470
- return NUMERIC_TYPES.includes(type);
3435
+ return NUMERIC_TYPES_SET.has(type);
3471
3436
  if (type.kind === "value") return typeof type.value === "number";
3472
3437
  if (type.kind === "numeric") return true;
3473
3438
  return false;
@@ -3475,7 +3440,7 @@ function isNumeric(type) {
3475
3440
  function isScalar(type) {
3476
3441
  if (isNumeric(type)) return true;
3477
3442
  if (typeof type === "string")
3478
- return SCALAR_TYPES.includes(type);
3443
+ return SCALAR_TYPES_SET.has(type);
3479
3444
  if (type.kind === "value")
3480
3445
  return ["string", "boolean", "number"].includes(typeof type.value);
3481
3446
  return false;
@@ -3483,7 +3448,7 @@ function isScalar(type) {
3483
3448
  function isCollection(type) {
3484
3449
  if (isIndexedCollection(type)) return true;
3485
3450
  if (typeof type === "string")
3486
- return COLLECTION_TYPES.includes(type);
3451
+ return COLLECTION_TYPES_SET.has(type);
3487
3452
  return ["collection", "set", "record", "dictionary"].includes(type.kind);
3488
3453
  }
3489
3454
  function isIndexedCollection(type) {
@@ -3522,7 +3487,7 @@ function narrow2(a, b) {
3522
3487
  if (b === "unknown") return a;
3523
3488
  if (isSubtype(a, b)) return a;
3524
3489
  if (isSubtype(b, a)) return b;
3525
- return superType(a, b);
3490
+ return "never";
3526
3491
  }
3527
3492
  function widen2(a, b) {
3528
3493
  if (a === b) return a;
@@ -3556,16 +3521,17 @@ var LOSSY_SUPERTYPE = /* @__PURE__ */ new Set([
3556
3521
  ]);
3557
3522
  function unionTypes(a, b) {
3558
3523
  const members = [];
3524
+ const keys = /* @__PURE__ */ new Set();
3559
3525
  const push = (t) => {
3560
3526
  if (typeof t === "object" && t.kind === "union") {
3561
3527
  for (const m of t.types) push(m);
3562
3528
  return;
3563
3529
  }
3564
3530
  const key = typeof t === "string" ? t : JSON.stringify(t);
3565
- if (!members.some(
3566
- (m) => (typeof m === "string" ? m : JSON.stringify(m)) === key
3567
- ))
3531
+ if (!keys.has(key)) {
3532
+ keys.add(key);
3568
3533
  members.push(t);
3534
+ }
3569
3535
  };
3570
3536
  push(a);
3571
3537
  push(b);
@@ -3577,48 +3543,225 @@ function narrow(...types) {
3577
3543
  if (types.length === 1) return types[0];
3578
3544
  return types.reduce((a, b) => narrow2(a, b));
3579
3545
  }
3580
- function widen(...types) {
3581
- if (types.length === 0) return "nothing";
3582
- if (types.length === 1) return types[0];
3583
- return types.reduce((a, b) => widen2(a, b));
3546
+ function widen(...types) {
3547
+ if (types.length === 0) return "nothing";
3548
+ if (types.length === 1) return types[0];
3549
+ return types.reduce((a, b) => widen2(a, b));
3550
+ }
3551
+ var SUPERTYPE_PROBE_ORDER = [
3552
+ "non_finite_number",
3553
+ "finite_integer",
3554
+ "integer",
3555
+ "finite_rational",
3556
+ "rational",
3557
+ "finite_real",
3558
+ "real",
3559
+ "imaginary",
3560
+ "finite_complex",
3561
+ "complex",
3562
+ "finite_number",
3563
+ "number",
3564
+ "list",
3565
+ "record",
3566
+ "dictionary",
3567
+ "set",
3568
+ "tuple",
3569
+ "indexed_collection",
3570
+ "collection",
3571
+ "scalar",
3572
+ "value",
3573
+ "function",
3574
+ "expression"
3575
+ ];
3576
+ var PRIMITIVE_SUPERTYPE_CACHE = /* @__PURE__ */ new Map();
3577
+ function superType(a, b) {
3578
+ if (a === b) return a;
3579
+ if (a === "any" || b === "any") return "any";
3580
+ if (a === "never") return b;
3581
+ if (b === "never") return a;
3582
+ if (a === "unknown") return b;
3583
+ if (b === "unknown") return a;
3584
+ if (a === "nothing") return b;
3585
+ if (b === "nothing") return a;
3586
+ if (typeof a === "string" && typeof b === "string") {
3587
+ const key = a < b ? `${a}|${b}` : `${b}|${a}`;
3588
+ let result = PRIMITIVE_SUPERTYPE_CACHE.get(key);
3589
+ if (result === void 0) {
3590
+ result = "any";
3591
+ for (const ancestor of SUPERTYPE_PROBE_ORDER) {
3592
+ const subtypes = PRIMITIVE_SUBTYPES_CLOSURE[ancestor];
3593
+ if (subtypes.has(a) && subtypes.has(b)) {
3594
+ result = ancestor;
3595
+ break;
3596
+ }
3597
+ }
3598
+ PRIMITIVE_SUPERTYPE_CACHE.set(key, result);
3599
+ }
3600
+ return result;
3601
+ }
3602
+ for (const ancestor of SUPERTYPE_PROBE_ORDER)
3603
+ if (isSubtype(a, ancestor) && isSubtype(b, ancestor)) return ancestor;
3604
+ return "any";
3605
+ }
3606
+
3607
+ // src/common/type/serialize.ts
3608
+ var NEGATION_PRECEDENCE = 3;
3609
+ var UNION_PRECEDENCE = 1;
3610
+ var INTERSECTION_PRECEDENCE = 2;
3611
+ var LIST_PRECEDENCE = 4;
3612
+ var RECORD_PRECEDENCE = 5;
3613
+ var DICTIONARY_PRECEDENCE = 6;
3614
+ var SET_PRECEDENCE = 7;
3615
+ var COLLECTION_PRECEDENCE = 8;
3616
+ var TUPLE_PRECEDENCE = 9;
3617
+ var SIGNATURE_PRECEDENCE = 10;
3618
+ var VALUE_PRECEDENCE = 11;
3619
+ function typeToString(type, precedence = 0) {
3620
+ if (typeof type === "string") return type;
3621
+ let result = "";
3622
+ switch (type.kind) {
3623
+ case "value":
3624
+ if (typeof type.value === "string") result = `"${type.value}"`;
3625
+ else if (typeof type.value === "boolean")
3626
+ result = type.value ? "true" : "false";
3627
+ else result = type.value.toString();
3628
+ break;
3629
+ case "reference":
3630
+ result = type.name;
3631
+ break;
3632
+ case "negation":
3633
+ result = `!${typeToString(type.type, NEGATION_PRECEDENCE)}`;
3634
+ break;
3635
+ case "union":
3636
+ result = type.types.map((t) => typeToString(t, UNION_PRECEDENCE)).join(" | ");
3637
+ break;
3638
+ case "intersection":
3639
+ result = type.types.map((t) => typeToString(t, INTERSECTION_PRECEDENCE)).join(" & ");
3640
+ break;
3641
+ case "expression":
3642
+ result = `expression<${symbolName(type.operator)}>`;
3643
+ break;
3644
+ case "symbol":
3645
+ result = `symbol<${symbolName(type.name)}>`;
3646
+ break;
3647
+ case "numeric":
3648
+ if (Number.isFinite(type.lower) && Number.isFinite(type.upper)) {
3649
+ result = `${type.type}<${type.lower}..${type.upper}>`;
3650
+ } else if (Number.isFinite(type.lower)) {
3651
+ result = `${type.type}<${type.lower}..>`;
3652
+ } else if (Number.isFinite(type.upper)) {
3653
+ result = `${type.type}<..${type.upper}>`;
3654
+ } else {
3655
+ result = `${type.type}`;
3656
+ }
3657
+ break;
3658
+ case "list":
3659
+ if (type.dimensions && typeof type.elements === "string" && NUMERIC_TYPES_SET.has(type.elements)) {
3660
+ if (type.dimensions === void 0) {
3661
+ if (type.elements === "number") result = "tensor";
3662
+ } else if (type.dimensions.length === 1) {
3663
+ if (type.elements === "number") {
3664
+ if (type.dimensions[0] < 0) result = "vector";
3665
+ else result = `vector<${type.dimensions[0]}>`;
3666
+ } else {
3667
+ if (type.dimensions[0] < 0)
3668
+ result = `vector<${typeToString(type.elements)}>`;
3669
+ else
3670
+ result = `vector<${typeToString(type.elements)}^${type.dimensions[0]}>`;
3671
+ }
3672
+ } else if (type.dimensions.length === 2) {
3673
+ const dims = type.dimensions;
3674
+ if (type.elements === "number") {
3675
+ if (dims[0] < 0 && dims[1] < 0) result = "matrix";
3676
+ else result = `matrix<${dims[0]}x${dims[1]}>`;
3677
+ } else {
3678
+ if (dims[0] < 0 && dims[1] < 0)
3679
+ result = `matrix<${typeToString(type.elements)}>`;
3680
+ else
3681
+ result = `matrix<${typeToString(type.elements)}^(${dims[0]}x${dims[1]})>`;
3682
+ }
3683
+ }
3684
+ }
3685
+ if (!result) {
3686
+ const dimensions = type.dimensions ? type.dimensions.length === 1 ? `^${type.dimensions[0].toString()}` : `^(${type.dimensions.join("x")})` : "";
3687
+ result = `list<${typeToString(type.elements)}${dimensions}>`;
3688
+ }
3689
+ break;
3690
+ case "record":
3691
+ const elements = Object.entries(type.elements).map(([key, value]) => `${key}: ${typeToString(value)}`).join(", ");
3692
+ result = `record<${elements}>`;
3693
+ break;
3694
+ case "dictionary":
3695
+ result = `dictionary<${typeToString(type.values)}>`;
3696
+ break;
3697
+ case "set":
3698
+ result = `set<${typeToString(type.elements)}>`;
3699
+ break;
3700
+ case "collection":
3701
+ result = `collection<${typeToString(type.elements)}>`;
3702
+ break;
3703
+ case "indexed_collection":
3704
+ result = `indexed_collection<${typeToString(type.elements)}>`;
3705
+ break;
3706
+ case "tuple":
3707
+ if (type.elements.length === 0) result = "tuple";
3708
+ else if (type.elements.length === 1) {
3709
+ const [el] = type.elements;
3710
+ result = `tuple<${namedElement(el)}>`;
3711
+ } else {
3712
+ result = "tuple<" + type.elements.map((el) => namedElement(el)).join(", ") + ">";
3713
+ }
3714
+ break;
3715
+ case "signature":
3716
+ const args = type.args ? type.args.map((arg) => namedElement(arg)).join(", ") : "";
3717
+ const optArgs = type.optArgs ? type.optArgs.map((arg) => namedElement(arg) + "?").join(", ") : "";
3718
+ const varArg = type.variadicArg ? type.variadicMin === 0 ? `${namedElement(type.variadicArg)}*` : `${namedElement(type.variadicArg)}+` : "";
3719
+ const argsList = [args, optArgs, varArg].filter((s) => s).join(", ");
3720
+ result = `(${argsList}) -> ${typeToString(type.result)}`;
3721
+ break;
3722
+ default:
3723
+ result = "error";
3724
+ }
3725
+ if (precedence > 0 && precedence > getPrecedence(type.kind))
3726
+ return `(${result})`;
3727
+ return result;
3728
+ }
3729
+ function namedElement(el) {
3730
+ if (el.name) return `${el.name}: ${typeToString(el.type)}`;
3731
+ return typeToString(el.type);
3584
3732
  }
3585
- function superType(a, b) {
3586
- if (a === b) return a;
3587
- if (a === "any" || b === "any") return "any";
3588
- if (a === "never") return b;
3589
- if (b === "never") return a;
3590
- if (a === "unknown") return b;
3591
- if (b === "unknown") return a;
3592
- if (a === "nothing") return b;
3593
- if (b === "nothing") return a;
3594
- if (commonSupertype(a, b, "non_finite_number")) return "non_finite_number";
3595
- if (commonSupertype(a, b, "finite_integer")) return "finite_integer";
3596
- if (commonSupertype(a, b, "integer")) return "integer";
3597
- if (commonSupertype(a, b, "finite_rational")) return "finite_rational";
3598
- if (commonSupertype(a, b, "rational")) return "rational";
3599
- if (commonSupertype(a, b, "finite_real")) return "finite_real";
3600
- if (commonSupertype(a, b, "real")) return "real";
3601
- if (commonSupertype(a, b, "imaginary")) return "imaginary";
3602
- if (commonSupertype(a, b, "finite_complex")) return "finite_complex";
3603
- if (commonSupertype(a, b, "complex")) return "complex";
3604
- if (commonSupertype(a, b, "finite_number")) return "finite_number";
3605
- if (commonSupertype(a, b, "number")) return "number";
3606
- if (commonSupertype(a, b, "list")) return "list";
3607
- if (commonSupertype(a, b, "record")) return "record";
3608
- if (commonSupertype(a, b, "dictionary")) return "dictionary";
3609
- if (commonSupertype(a, b, "set")) return "set";
3610
- if (commonSupertype(a, b, "tuple")) return "tuple";
3611
- if (commonSupertype(a, b, "indexed_collection")) return "indexed_collection";
3612
- if (commonSupertype(a, b, "collection")) return "collection";
3613
- if (commonSupertype(a, b, "scalar")) return "scalar";
3614
- if (commonSupertype(a, b, "value")) return "value";
3615
- if (commonSupertype(a, b, "function")) return "function";
3616
- if (commonSupertype(a, b, "expression")) return "expression";
3617
- return "any";
3733
+ function symbolName(name) {
3734
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) return name;
3735
+ return `\`${name}\``;
3618
3736
  }
3619
- function commonSupertype(a, b, ancestor) {
3620
- if (isSubtype(a, ancestor) && isSubtype(b, ancestor)) return true;
3621
- return false;
3737
+ function getPrecedence(kind) {
3738
+ switch (kind) {
3739
+ case "negation":
3740
+ return NEGATION_PRECEDENCE;
3741
+ case "union":
3742
+ return UNION_PRECEDENCE;
3743
+ case "intersection":
3744
+ return INTERSECTION_PRECEDENCE;
3745
+ case "list":
3746
+ return LIST_PRECEDENCE;
3747
+ case "record":
3748
+ return RECORD_PRECEDENCE;
3749
+ case "dictionary":
3750
+ return DICTIONARY_PRECEDENCE;
3751
+ case "set":
3752
+ return SET_PRECEDENCE;
3753
+ case "collection":
3754
+ case "indexed_collection":
3755
+ return COLLECTION_PRECEDENCE;
3756
+ case "tuple":
3757
+ return TUPLE_PRECEDENCE;
3758
+ case "signature":
3759
+ return SIGNATURE_PRECEDENCE;
3760
+ case "value":
3761
+ return VALUE_PRECEDENCE;
3762
+ default:
3763
+ return 0;
3764
+ }
3622
3765
  }
3623
3766
 
3624
3767
  // src/common/type/utils.ts
@@ -3727,6 +3870,12 @@ function sym(expr) {
3727
3870
  return expr?._kind === "symbol" ? expr.symbol : void 0;
3728
3871
  }
3729
3872
 
3873
+ // src/compute-engine/boxed-expression/constraint-subject.ts
3874
+ var EMPTY_FACT_INDEX = Object.freeze({
3875
+ bySubject: /* @__PURE__ */ new Map(),
3876
+ membership: /* @__PURE__ */ new Map()
3877
+ });
3878
+
3730
3879
  // src/compute-engine/boxed-expression/stochastic-equal.ts
3731
3880
  var WELL_KNOWN_POINTS = [
3732
3881
  0,
@@ -3975,6 +4124,7 @@ function applicable(fn) {
3975
4124
  }
3976
4125
 
3977
4126
  // src/compute-engine/collection-utils.ts
4127
+ var MAX_SIZE_EAGER_COLLECTION = 100;
3978
4128
  function isFiniteIndexedCollection(col) {
3979
4129
  return (col.isFiniteCollection ?? false) && col.isIndexedCollection;
3980
4130
  }
@@ -4603,12 +4753,14 @@ function dictionaryFromExpression(expr) {
4603
4753
  if (expr === null) return null;
4604
4754
  if (isDictionaryObject(expr)) return expr;
4605
4755
  const kv = keyValuePair(expr);
4606
- if (kv) return { [kv[0]]: kv[1] };
4756
+ if (kv)
4757
+ return {
4758
+ dict: { [kv[0]]: expressionToDictionaryValue(kv[1]) ?? "Nothing" }
4759
+ };
4607
4760
  if (operator(expr) === "Dictionary") {
4608
4761
  const dict = {};
4609
- const ops = operands(expr);
4610
- for (let i = 1; i < nops(expr); i++) {
4611
- const kv2 = keyValuePair(ops[i]);
4762
+ for (const op of operands(expr)) {
4763
+ const kv2 = keyValuePair(op);
4612
4764
  if (kv2) {
4613
4765
  dict[kv2[0]] = expressionToDictionaryValue(kv2[1]) ?? "Nothing";
4614
4766
  }
@@ -6542,6 +6694,7 @@ var DEFINITIONS_CORE = [
6542
6694
  }
6543
6695
  }
6544
6696
  if (!variable) return null;
6697
+ if (symbol(variable) === null) return null;
6545
6698
  parser.skipSpace();
6546
6699
  const fn = parser.parseExpression({ minPrec: 740 });
6547
6700
  if (!fn) return null;
@@ -6728,7 +6881,7 @@ function parseTextRun(parser, style) {
6728
6881
  if (runs.length === 1) body = runs[0];
6729
6882
  else {
6730
6883
  if (runs.every((x) => stringValue(x) !== null))
6731
- body = "'" + runs.map((x) => stringValue(x)).join() + "'";
6884
+ body = "'" + runs.map((x) => stringValue(x)).join("") + "'";
6732
6885
  else body = ["Text", ...runs];
6733
6886
  }
6734
6887
  return style ? ["Annotated", body, dictionaryFromEntries(style)] : body;
@@ -8261,6 +8414,8 @@ function serializeMultiply(serializer, expr) {
8261
8414
  const h = operator(arg);
8262
8415
  if (prevWasNumber && (h === "Divide" || h === "Rational")) {
8263
8416
  result = latexTemplate(serializer.options.multiply, result, term);
8417
+ } else if (/^\d/.test(term)) {
8418
+ result = latexTemplate(serializer.options.multiply, result, term);
8264
8419
  } else if (!serializer.options.invisibleMultiply) {
8265
8420
  result = joinLatex([result, term]);
8266
8421
  } else {
@@ -9706,7 +9861,8 @@ function parseTrig(op) {
9706
9861
  minPrec: MULTIPLICATION_PRECEDENCE,
9707
9862
  condition: (parser2) => trigCommands[parser2.peek] || (until?.condition?.(parser2) ?? false)
9708
9863
  });
9709
- const head = fn === "Arctan" && args?.length === 2 ? "Arctan2" : fn;
9864
+ const isTwoArgArctan = args?.length === 2 && (fn === "Arctan" || Array.isArray(fn) && fn[0] === "InverseFunction" && fn[1] === "Tan");
9865
+ const head = isTwoArgArctan ? "Arctan2" : fn;
9710
9866
  const appliedFn = args === null ? fn : typeof head === "string" ? [head, ...args] : ["Apply", head, ...args];
9711
9867
  return sup === null ? appliedFn : ["Power", appliedFn, sup];
9712
9868
  };
@@ -11993,6 +12149,30 @@ var POSSIBLE_EMOJI = `(?:${ZWJ_ELEMENT})(${ZWJ}${ZWJ_ELEMENT})*`;
11993
12149
  var SOME_EMOJI = new RegExp(`(?:${POSSIBLE_EMOJI})+`, "u");
11994
12150
  var EMOJIS = new RegExp(`^(?:${POSSIBLE_EMOJI})+$`, "u");
11995
12151
 
12152
+ // src/compute-engine/latex-syntax/parse.ts
12153
+ var PARSE_TOKEN_EXCLUDED = /* @__PURE__ */ new Set([
12154
+ ...'!"#$%&(),/;:?@[]\\`|~'.split(""),
12155
+ "\\left",
12156
+ "\\bigl",
12157
+ "\\mleft"
12158
+ ]);
12159
+ var TEX_UNIT_TOKENS = [
12160
+ "pt",
12161
+ "em",
12162
+ "mu",
12163
+ "ex",
12164
+ "mm",
12165
+ "cm",
12166
+ "in",
12167
+ "bp",
12168
+ "sp",
12169
+ "dd",
12170
+ "cc",
12171
+ "pc",
12172
+ "nc",
12173
+ "nd"
12174
+ ].map((unit) => [...unit]);
12175
+
11996
12176
  // src/compute-engine/boxed-expression/utils.ts
11997
12177
  function isValueDef(def) {
11998
12178
  return def !== void 0 && "value" in def;
@@ -12028,6 +12208,50 @@ function flatten(ops, operator2, canonicalize = true) {
12028
12208
  return ys;
12029
12209
  }
12030
12210
 
12211
+ // src/common/fuzzy-string-match.ts
12212
+ function levenshtein(source, target) {
12213
+ if (source === target) return 0;
12214
+ if (source.length === 0) return target.length;
12215
+ if (target.length === 0) return source.length;
12216
+ let prevRow = Array.from(
12217
+ { length: source.length + 1 },
12218
+ (_, j) => j
12219
+ );
12220
+ let currRow = new Array(source.length + 1);
12221
+ for (let i = 1; i <= target.length; i++) {
12222
+ currRow[0] = i;
12223
+ for (let j = 1; j <= source.length; j++) {
12224
+ const cost = source[j - 1] === target[i - 1] ? 0 : 1;
12225
+ currRow[j] = Math.min(
12226
+ prevRow[j] + 1,
12227
+ // deletion
12228
+ currRow[j - 1] + 1,
12229
+ // insertion
12230
+ prevRow[j - 1] + cost
12231
+ // substitution
12232
+ );
12233
+ }
12234
+ [prevRow, currRow] = [currRow, prevRow];
12235
+ }
12236
+ return prevRow[source.length];
12237
+ }
12238
+ function fuzzyStringMatch(invalidWord, validWords) {
12239
+ const threshold = 7;
12240
+ let bestMatch = null;
12241
+ let minDistance = Infinity;
12242
+ const invalidLength = invalidWord.length;
12243
+ for (const word of validWords) {
12244
+ if (Math.abs(invalidLength - word.length) > threshold) continue;
12245
+ const distance = levenshtein(invalidWord, word);
12246
+ if (distance === 0) return word;
12247
+ if (distance <= threshold && distance < minDistance) {
12248
+ minDistance = distance;
12249
+ bestMatch = word;
12250
+ }
12251
+ }
12252
+ return bestMatch;
12253
+ }
12254
+
12031
12255
  // src/compute-engine/boxed-expression/validate.ts
12032
12256
  function checkArity(ce, ops, count) {
12033
12257
  ops = flatten(ops);
@@ -12959,21 +13183,249 @@ var Complex = class _Complex {
12959
13183
  isInfinite() {
12960
13184
  return !(this["isNaN"]() || this["isFinite"]());
12961
13185
  }
12962
- };
12963
- Complex["ZERO"] = new Complex(0, 0);
12964
- Complex["ONE"] = new Complex(1, 0);
12965
- Complex["I"] = new Complex(0, 1);
12966
- Complex["PI"] = new Complex(Math.PI, 0);
12967
- Complex["E"] = new Complex(Math.E, 0);
12968
- Complex["INFINITY"] = new Complex(Infinity, Infinity);
12969
- Complex["NAN"] = new Complex(NaN, NaN);
12970
- Complex["EPSILON"] = 1e-15;
12971
-
12972
- // src/compute-engine/boxed-expression/numerics.ts
12973
- function toInteger(expr) {
12974
- if (!isNumber(expr)) return null;
12975
- const num = expr.numericValue;
12976
- return Math.round(typeof num === "number" ? num : num.re);
13186
+ };
13187
+ Complex["ZERO"] = new Complex(0, 0);
13188
+ Complex["ONE"] = new Complex(1, 0);
13189
+ Complex["I"] = new Complex(0, 1);
13190
+ Complex["PI"] = new Complex(Math.PI, 0);
13191
+ Complex["E"] = new Complex(Math.E, 0);
13192
+ Complex["INFINITY"] = new Complex(Infinity, Infinity);
13193
+ Complex["NAN"] = new Complex(NaN, NaN);
13194
+ Complex["EPSILON"] = 1e-15;
13195
+
13196
+ // src/compute-engine/boxed-expression/numerics.ts
13197
+ function asSmallInteger(expr) {
13198
+ if (expr === void 0 || expr === null) return null;
13199
+ if (typeof expr === "number") {
13200
+ if (Number.isInteger(expr) && expr >= -SMALL_INTEGER && expr <= SMALL_INTEGER)
13201
+ return expr;
13202
+ return null;
13203
+ }
13204
+ if (!isNumber(expr)) return null;
13205
+ const num = expr.numericValue;
13206
+ if (typeof num === "number") {
13207
+ if (Number.isInteger(num) && num >= -SMALL_INTEGER && num <= SMALL_INTEGER)
13208
+ return num;
13209
+ return null;
13210
+ }
13211
+ if (num.im !== 0) return null;
13212
+ const n = num.re;
13213
+ if (Number.isInteger(n) && n >= -SMALL_INTEGER && n <= SMALL_INTEGER)
13214
+ return Number(n);
13215
+ return null;
13216
+ }
13217
+ function toInteger(expr) {
13218
+ if (!isNumber(expr)) return null;
13219
+ const num = expr.numericValue;
13220
+ return Math.round(typeof num === "number" ? num : num.re);
13221
+ }
13222
+
13223
+ // src/compute-engine/library/logic-analysis.ts
13224
+ function filterValuesWithCondition(values, variable, conditionExpr, _ce) {
13225
+ return values.filter((value) => {
13226
+ const substituted = conditionExpr.subs({ [variable]: value });
13227
+ const result = substituted.evaluate();
13228
+ return sym(result) === "True";
13229
+ });
13230
+ }
13231
+ function extractFiniteDomainWithReason(condition, ce) {
13232
+ if (condition.operator !== "Element") {
13233
+ return { status: "error", reason: "expected-element-expression" };
13234
+ }
13235
+ if (!isFunction2(condition)) {
13236
+ return { status: "error", reason: "expected-element-expression" };
13237
+ }
13238
+ const variable = isSymbol2(condition.op1) ? condition.op1.symbol : void 0;
13239
+ if (!variable) {
13240
+ return { status: "error", reason: "expected-index-variable" };
13241
+ }
13242
+ const domain = condition.op2;
13243
+ if (!domain) {
13244
+ return { status: "error", reason: "expected-domain" };
13245
+ }
13246
+ const maybeCondition = condition.op3;
13247
+ const filterCondition = condition.nops >= 3 && maybeCondition && sym(maybeCondition) !== "Nothing" ? maybeCondition : null;
13248
+ const successResult = (values) => {
13249
+ if (filterCondition) {
13250
+ const filteredValues = filterValuesWithCondition(
13251
+ values,
13252
+ variable,
13253
+ filterCondition,
13254
+ ce
13255
+ );
13256
+ return { status: "success", variable, values: filteredValues };
13257
+ }
13258
+ return { status: "success", variable, values };
13259
+ };
13260
+ if (domain.operator === "Set" || domain.operator === "List") {
13261
+ const values = isFunction2(domain) ? domain.ops : void 0;
13262
+ if (values && values.length <= 1e3) {
13263
+ if (domain.operator === "List" && values.length === 2) {
13264
+ const start = asSmallInteger(values[0]);
13265
+ const end = asSmallInteger(values[1]);
13266
+ if (start !== null && end !== null) {
13267
+ const count = end - start + 1;
13268
+ if (count > 0 && count <= 1e3) {
13269
+ const rangeValues = [];
13270
+ for (let i = start; i <= end; i++) {
13271
+ rangeValues.push(ce.number(i));
13272
+ }
13273
+ return successResult(rangeValues);
13274
+ }
13275
+ if (count > 1e3) {
13276
+ return {
13277
+ status: "non-enumerable",
13278
+ variable,
13279
+ domain,
13280
+ reason: "domain-too-large"
13281
+ };
13282
+ }
13283
+ }
13284
+ }
13285
+ return successResult([...values]);
13286
+ }
13287
+ if (values && values.length > 1e3) {
13288
+ return {
13289
+ status: "non-enumerable",
13290
+ variable,
13291
+ domain,
13292
+ reason: "domain-too-large"
13293
+ };
13294
+ }
13295
+ return { status: "error", reason: "empty-domain" };
13296
+ }
13297
+ if (isFunction2(domain, "Range")) {
13298
+ const start = asSmallInteger(domain.op1);
13299
+ const end = asSmallInteger(domain.op2);
13300
+ const step = domain.ops.length >= 3 ? asSmallInteger(domain.op3) : 1;
13301
+ if (start !== null && end !== null && step !== null && step !== 0) {
13302
+ const count = Math.floor((end - start) / step) + 1;
13303
+ if (count > 0 && count <= 1e3) {
13304
+ const values = [];
13305
+ for (let i = start; step > 0 ? i <= end : i >= end; i += step) {
13306
+ values.push(ce.number(i));
13307
+ }
13308
+ return successResult(values);
13309
+ }
13310
+ if (count > 1e3) {
13311
+ return {
13312
+ status: "non-enumerable",
13313
+ variable,
13314
+ domain,
13315
+ reason: "domain-too-large"
13316
+ };
13317
+ }
13318
+ }
13319
+ return {
13320
+ status: "non-enumerable",
13321
+ variable,
13322
+ domain,
13323
+ reason: "non-integer-bounds"
13324
+ };
13325
+ }
13326
+ if (isFunction2(domain, "Interval")) {
13327
+ let op1 = domain.op1;
13328
+ let op2 = domain.op2;
13329
+ let openStart = false;
13330
+ let openEnd = false;
13331
+ if (isFunction2(op1, "Open")) {
13332
+ openStart = true;
13333
+ op1 = op1.op1;
13334
+ } else if (isFunction2(op1, "Closed")) {
13335
+ op1 = op1.op1;
13336
+ }
13337
+ if (isFunction2(op2, "Open")) {
13338
+ openEnd = true;
13339
+ op2 = op2.op1;
13340
+ } else if (isFunction2(op2, "Closed")) {
13341
+ op2 = op2.op1;
13342
+ }
13343
+ let start = asSmallInteger(op1);
13344
+ let end = asSmallInteger(op2);
13345
+ if (start !== null && end !== null) {
13346
+ if (openStart) start += 1;
13347
+ if (openEnd) end -= 1;
13348
+ const count = end - start + 1;
13349
+ if (count > 0 && count <= 1e3) {
13350
+ const values = [];
13351
+ for (let i = start; i <= end; i++) {
13352
+ values.push(ce.number(i));
13353
+ }
13354
+ return successResult(values);
13355
+ }
13356
+ if (count > 1e3) {
13357
+ return {
13358
+ status: "non-enumerable",
13359
+ variable,
13360
+ domain,
13361
+ reason: "domain-too-large"
13362
+ };
13363
+ }
13364
+ }
13365
+ return {
13366
+ status: "non-enumerable",
13367
+ variable,
13368
+ domain,
13369
+ reason: "non-integer-bounds"
13370
+ };
13371
+ }
13372
+ const domainSymbol = sym(domain);
13373
+ if (domainSymbol) {
13374
+ const knownInfiniteSets = [
13375
+ "Integers",
13376
+ "NonNegativeIntegers",
13377
+ "PositiveIntegers",
13378
+ "NegativeIntegers",
13379
+ "Rationals",
13380
+ "Reals",
13381
+ "PositiveReals",
13382
+ "NonNegativeReals",
13383
+ "NegativeReals",
13384
+ "NonPositiveReals",
13385
+ "ExtendedReals",
13386
+ "Complexes",
13387
+ "ImaginaryNumbers",
13388
+ "Numbers",
13389
+ "ExtendedComplexes",
13390
+ "AlgebraicNumbers",
13391
+ "TranscendentalNumbers"
13392
+ ];
13393
+ if (knownInfiniteSets.includes(domainSymbol)) {
13394
+ return {
13395
+ status: "non-enumerable",
13396
+ variable,
13397
+ domain,
13398
+ reason: "infinite-domain"
13399
+ };
13400
+ }
13401
+ const domainValue = domain.value;
13402
+ if (domainValue && domainValue.operator === "Set" && isFunction2(domainValue)) {
13403
+ const values = domainValue.ops;
13404
+ if (values && values.length <= 1e3) {
13405
+ return successResult([...values]);
13406
+ }
13407
+ if (values && values.length > 1e3) {
13408
+ return {
13409
+ status: "non-enumerable",
13410
+ variable,
13411
+ domain,
13412
+ reason: "domain-too-large"
13413
+ };
13414
+ }
13415
+ }
13416
+ return {
13417
+ status: "non-enumerable",
13418
+ variable,
13419
+ domain,
13420
+ reason: "unknown-domain"
13421
+ };
13422
+ }
13423
+ return {
13424
+ status: "non-enumerable",
13425
+ variable,
13426
+ domain,
13427
+ reason: "unrecognized-domain-type"
13428
+ };
12977
13429
  }
12978
13430
 
12979
13431
  // src/compute-engine/numerics/interval.ts
@@ -13030,6 +13482,11 @@ function interval(expr) {
13030
13482
  }
13031
13483
  return void 0;
13032
13484
  }
13485
+ function intervalContains(int, val) {
13486
+ if (int.openStart ? val <= int.start : val < int.start) return false;
13487
+ if (int.openEnd ? val >= int.end : val > int.end) return false;
13488
+ return true;
13489
+ }
13033
13490
 
13034
13491
  // src/compute-engine/numerics/random.ts
13035
13492
  function deterministicRandom(seed) {
@@ -13046,8 +13503,236 @@ function canonical(ce, xs, scope) {
13046
13503
  return xs.map((x) => ce.expr(x, { scope }));
13047
13504
  }
13048
13505
 
13506
+ // src/common/type/reduce.ts
13507
+ function reduceType(type) {
13508
+ if (typeof type === "string") {
13509
+ if (!isValidPrimitiveType(type)) return "error";
13510
+ return type;
13511
+ }
13512
+ switch (type.kind) {
13513
+ case "union":
13514
+ return reduceUnionType(type);
13515
+ case "intersection":
13516
+ return reduceIntersectionType(type);
13517
+ case "negation":
13518
+ return reduceNegationType(type);
13519
+ case "collection":
13520
+ case "indexed_collection":
13521
+ return reduceCollectionType(type.kind, type);
13522
+ case "list":
13523
+ return reduceListType(type);
13524
+ case "set":
13525
+ return reduceSetType(type);
13526
+ case "tuple":
13527
+ return reduceTupleType(type);
13528
+ case "record":
13529
+ return reduceRecordType(type);
13530
+ case "dictionary":
13531
+ return reduceDictionaryType(type);
13532
+ case "signature":
13533
+ return reduceSignatureType(type);
13534
+ case "value":
13535
+ return type;
13536
+ case "reference":
13537
+ return type;
13538
+ default:
13539
+ throw new Error(`Unknown type kind: ${type}`);
13540
+ }
13541
+ }
13542
+ function decorate(t) {
13543
+ if (typeof t !== "object") return t;
13544
+ if (Object.isFrozen(t) || Object.prototype.hasOwnProperty.call(t, "toString"))
13545
+ return t;
13546
+ Object.defineProperty(t, "toString", { value: () => typeToString(t) });
13547
+ return t;
13548
+ }
13549
+ function reduceMembers(types) {
13550
+ const result = [];
13551
+ const seen = /* @__PURE__ */ new Set();
13552
+ for (const t of types) {
13553
+ const reduced = reduceType(t);
13554
+ const key = typeof reduced === "string" ? reduced : typeToString(reduced);
13555
+ if (!seen.has(key)) {
13556
+ seen.add(key);
13557
+ result.push(reduced);
13558
+ }
13559
+ }
13560
+ return result;
13561
+ }
13562
+ function reduceNegationType(type) {
13563
+ const reducedType = reduceType(type.type);
13564
+ if (reducedType === "nothing") return "any";
13565
+ if (reducedType === "any") return "nothing";
13566
+ return decorate({ kind: "negation", type: reducedType });
13567
+ }
13568
+ function reduceUnionType(type) {
13569
+ const reducedTypes = reduceMembers(type.types);
13570
+ if (reducedTypes.length === 0) return "never";
13571
+ if (reducedTypes.some((type2) => type2 === "error")) return "error";
13572
+ if (reducedTypes.length === 1) return decorate(reducedTypes[0]);
13573
+ const acc = [];
13574
+ for (const current of reducedTypes) {
13575
+ if (acc.some((t) => isSubtype(current, t))) continue;
13576
+ for (let i = acc.length - 1; i >= 0; i--)
13577
+ if (isSubtype(acc[i], current)) acc.splice(i, 1);
13578
+ acc.push(current);
13579
+ }
13580
+ if (acc.length === 1) return decorate(acc[0]);
13581
+ return decorate({ kind: "union", types: acc });
13582
+ }
13583
+ function meet2(a, b) {
13584
+ if (isSubtype(a, b)) return a;
13585
+ if (isSubtype(b, a)) return b;
13586
+ if (typeof a === "object" && a.kind === "union") return meetUnion(a.types, b);
13587
+ if (typeof b === "object" && b.kind === "union") return meetUnion(b.types, a);
13588
+ if (typeof a === "string" && typeof b === "string") {
13589
+ const maximals = meetPrimitiveTypes(a, b);
13590
+ if (maximals.length === 0) return "nothing";
13591
+ if (maximals.length === 1) return maximals[0];
13592
+ return { kind: "union", types: maximals };
13593
+ }
13594
+ return "nothing";
13595
+ }
13596
+ function meetUnion(types, b) {
13597
+ const members = types.map((t) => meet2(t, b)).filter((t) => t !== "nothing");
13598
+ if (members.length === 0) return "nothing";
13599
+ if (members.length === 1) return members[0];
13600
+ return reduceUnionType({ kind: "union", types: members });
13601
+ }
13602
+ function reduceIntersectionType(type) {
13603
+ const reducedTypes = reduceMembers(type.types);
13604
+ if (reducedTypes.length === 0) return "nothing";
13605
+ if (reducedTypes.some((type2) => type2 === "error")) return "error";
13606
+ let result = reducedTypes[0];
13607
+ for (let i = 1; i < reducedTypes.length; i++) {
13608
+ result = meet2(result, reducedTypes[i]);
13609
+ if (result === "nothing") return "nothing";
13610
+ }
13611
+ return decorate(result);
13612
+ }
13613
+ function reduceCollectionType(kind, type) {
13614
+ const reducedType = reduceType(type.elements);
13615
+ if (reducedType === "error") return "error";
13616
+ if (reducedType === "nothing") return decorate({ kind, elements: "nothing" });
13617
+ if (reducedType === "any") return kind;
13618
+ return decorate({
13619
+ ...type,
13620
+ elements: reducedType
13621
+ });
13622
+ }
13623
+ function reduceListType(type) {
13624
+ const reducedType = reduceType(type.elements);
13625
+ if (reducedType === "error") return "error";
13626
+ if (reducedType === "nothing")
13627
+ return decorate({ kind: "list", elements: "nothing" });
13628
+ if (reducedType === "any") return "list";
13629
+ let dimensions = type.dimensions;
13630
+ if (dimensions) {
13631
+ dimensions = dimensions.filter((dim) => dim >= 1 || dim === -1);
13632
+ if (dimensions.length === 0) return "nothing";
13633
+ }
13634
+ return decorate({
13635
+ ...type,
13636
+ dimensions,
13637
+ elements: reducedType
13638
+ });
13639
+ }
13640
+ function reduceSetType(type) {
13641
+ const reducedType = reduceType(type.elements);
13642
+ if (reducedType === "error") return "error";
13643
+ if (reducedType === "nothing")
13644
+ return decorate({ kind: "set", elements: "nothing" });
13645
+ if (reducedType === "any") return "set";
13646
+ return decorate({
13647
+ ...type,
13648
+ elements: reducedType
13649
+ });
13650
+ }
13651
+ function reduceTupleType(type) {
13652
+ let reducedElements = type.elements.map((element) => ({
13653
+ ...element,
13654
+ type: reduceType(element.type)
13655
+ }));
13656
+ if (reducedElements.length === 0) return "nothing";
13657
+ if (reducedElements.some((element) => element.type === "error"))
13658
+ return "error";
13659
+ reducedElements = reducedElements.filter(
13660
+ (element) => element.type !== "nothing"
13661
+ );
13662
+ return decorate({
13663
+ ...type,
13664
+ elements: reducedElements
13665
+ });
13666
+ }
13667
+ function reduceRecordType(type) {
13668
+ let reducedElements = {};
13669
+ for (const [key, value] of Object.entries(type.elements))
13670
+ reducedElements[key] = reduceType(value);
13671
+ if (Object.values(reducedElements).some((type2) => type2 === "error"))
13672
+ return "error";
13673
+ reducedElements = Object.fromEntries(
13674
+ Object.entries(reducedElements).filter(([_, value]) => value !== "nothing")
13675
+ );
13676
+ if (Object.keys(reducedElements).length === 0) return "record";
13677
+ return decorate({
13678
+ ...type,
13679
+ elements: reducedElements
13680
+ });
13681
+ }
13682
+ function reduceDictionaryType(type) {
13683
+ const reducedValues = reduceType(type.values);
13684
+ if (reducedValues === "error") return "error";
13685
+ if (reducedValues === "nothing") return "error";
13686
+ if (reducedValues === "any" || reducedValues === "unknown") return "any";
13687
+ return decorate({ kind: "dictionary", values: reducedValues });
13688
+ }
13689
+ function reduceSignatureType(type) {
13690
+ const reducedArgs = type.args?.map((arg) => ({
13691
+ ...arg,
13692
+ type: reduceType(arg.type)
13693
+ }));
13694
+ let reducedOptArgs = type.optArgs?.map((arg) => ({
13695
+ ...arg,
13696
+ type: reduceType(arg.type)
13697
+ }));
13698
+ let reducedVarArg = type.variadicArg ? {
13699
+ ...type.variadicArg,
13700
+ type: reduceType(type.variadicArg.type)
13701
+ } : void 0;
13702
+ const reducedResult = reduceType(type.result);
13703
+ if (reducedArgs?.some((arg) => arg.type === "error")) return "error";
13704
+ if (reducedOptArgs?.some((arg) => arg.type === "error")) return "error";
13705
+ if (reducedVarArg?.type === "error") return "error";
13706
+ if (reducedResult === "error") return "error";
13707
+ reducedOptArgs = reducedOptArgs?.filter((arg) => arg.type !== "nothing");
13708
+ if (reducedArgs?.length === 0) reducedOptArgs = void 0;
13709
+ if (reducedOptArgs?.length === 0) reducedOptArgs = void 0;
13710
+ if (reducedVarArg?.type === "nothing") reducedVarArg = void 0;
13711
+ return decorate({
13712
+ ...type,
13713
+ args: reducedArgs,
13714
+ optArgs: reducedOptArgs,
13715
+ variadicArg: reducedVarArg,
13716
+ variadicMin: reducedVarArg ? type.variadicMin : void 0,
13717
+ result: reducedResult
13718
+ });
13719
+ }
13720
+
13721
+ // src/compute-engine/library/sets.ts
13722
+ function typeIntersection(a, b) {
13723
+ return reduceType({ kind: "intersection", types: [a, b] });
13724
+ }
13725
+ function typeMembership(x, t) {
13726
+ const vt = x.type;
13727
+ if (vt.matches(t)) return true;
13728
+ if (typeIntersection(vt.type, t) === "nothing") return false;
13729
+ if (isNumber(x)) return false;
13730
+ return void 0;
13731
+ }
13732
+
13049
13733
  // src/compute-engine/library/collections.ts
13050
13734
  var DEFAULT_LINSPACE_COUNT = 50;
13735
+ var SET_BASE_HANDLERS = basicIndexedCollectionHandlers();
13051
13736
  var COLLECTIONS_LIBRARY = {
13052
13737
  //
13053
13738
  // Data Structures
@@ -13070,11 +13755,38 @@ var COLLECTIONS_LIBRARY = {
13070
13755
  },
13071
13756
  // Extensional set. Elements do not repeat. The order of the elements is not significant.
13072
13757
  // For intensional set, use `Filter` with a condition, e.g. `Filter(RealNumbers, _ > 0)`
13758
+ //
13759
+ // A `Set` expression can also be a set-builder (comprehension), e.g.
13760
+ // `["Set", body, ["Element", k, domain, cond?]]` or
13761
+ // `["Set", body, ["Condition", ...]]` (see `parseSetComprehension()`).
13762
+ // Comprehensions are not literal 2-element sets: their elements are the
13763
+ // substituted bodies over the (filtered) domain.
13073
13764
  Set: {
13074
13765
  complexity: 8200,
13075
13766
  signature: "(any*) -> set",
13076
- type: (ops, { engine: _ce }) => parseType(`set<${BoxedType.widen(...ops.map((op) => op.type))}>`),
13767
+ type: (ops, { engine: _ce }) => {
13768
+ if (parseSetComprehension(ops) !== null) return parseType("set");
13769
+ return parseType(`set<${BoxedType.widen(...ops.map((op) => op.type))}>`);
13770
+ },
13077
13771
  canonical: canonicalSet,
13772
+ // The `lazy` flag suppresses the default operand evaluation: evaluating
13773
+ // the operands of a comprehension would mangle its indexing set (e.g.
13774
+ // the condition `gcd(n,k) = 1` with a free `k` evaluates to `False`).
13775
+ // Literal elements are evaluated explicitly in the `evaluate` handler.
13776
+ lazy: true,
13777
+ evaluate: (ops, { engine: ce, numericApproximation, materialization }) => {
13778
+ const comp = parseSetComprehension(ops);
13779
+ if (comp !== null) {
13780
+ const elements = enumerateSetComprehension(comp);
13781
+ if (elements === void 0 || elements.length > MAX_SIZE_EAGER_COLLECTION)
13782
+ return void 0;
13783
+ return ce.function("Set", elements);
13784
+ }
13785
+ return ce.function(
13786
+ "Set",
13787
+ ops.map((op) => op.evaluate({ numericApproximation, materialization }))
13788
+ );
13789
+ },
13078
13790
  eq: (a, b) => {
13079
13791
  if (a.operator !== b.operator) return false;
13080
13792
  if (!isFunction2(a) || !isFunction2(b)) return false;
@@ -13083,10 +13795,62 @@ var COLLECTIONS_LIBRARY = {
13083
13795
  return a.ops.every(has);
13084
13796
  },
13085
13797
  collection: {
13086
- ...basicIndexedCollectionHandlers(),
13798
+ ...SET_BASE_HANDLERS,
13087
13799
  // A set is not indexable
13088
13800
  at: void 0,
13089
- indexWhere: void 0
13801
+ indexWhere: void 0,
13802
+ // A comprehension computes its elements on demand
13803
+ isLazy: (expr) => isFunction2(expr) && parseSetComprehension(expr.ops) !== null,
13804
+ count: (expr) => {
13805
+ if (!isFunction2(expr)) return 0;
13806
+ const comp = parseSetComprehension(expr.ops);
13807
+ if (comp === null) return expr.nops;
13808
+ return enumerateSetComprehension(comp)?.length;
13809
+ },
13810
+ isEmpty: (expr) => {
13811
+ if (!isFunction2(expr)) return true;
13812
+ const comp = parseSetComprehension(expr.ops);
13813
+ if (comp === null) return expr.nops === 0;
13814
+ const elements = enumerateSetComprehension(comp);
13815
+ return elements === void 0 ? void 0 : elements.length === 0;
13816
+ },
13817
+ isFinite: (expr) => {
13818
+ if (!isFunction2(expr)) return true;
13819
+ const comp = parseSetComprehension(expr.ops);
13820
+ if (comp === null) return true;
13821
+ if (enumerateSetComprehension(comp) !== void 0) return true;
13822
+ if (comp.domain?.isFiniteCollection === true) return true;
13823
+ return void 0;
13824
+ },
13825
+ iterator: (expr) => {
13826
+ if (!isFunction2(expr)) return SET_BASE_HANDLERS.iterator(expr);
13827
+ const comp = parseSetComprehension(expr.ops);
13828
+ if (comp === null) return SET_BASE_HANDLERS.iterator(expr);
13829
+ const elements = enumerateSetComprehension(comp);
13830
+ if (elements === void 0) return void 0;
13831
+ let i = 0;
13832
+ return {
13833
+ next: () => i >= elements.length ? { value: void 0, done: true } : { value: elements[i++], done: false }
13834
+ };
13835
+ },
13836
+ // Three-valued membership: `true` when an element matches, `false`
13837
+ // only when every element is definitively different from `target`
13838
+ // (concrete values), `undefined` otherwise — e.g. a symbolic target
13839
+ // (`Element(ω, {-1, 1})`) is indeterminate, not refuted.
13840
+ contains: (expr, target) => {
13841
+ if (!isFunction2(expr)) return void 0;
13842
+ const comp = parseSetComprehension(expr.ops);
13843
+ if (comp !== null) return setComprehensionContains(comp, target);
13844
+ return literalSetContains(expr.ops, target);
13845
+ },
13846
+ elttype: (expr) => {
13847
+ if (!isFunction2(expr)) return SET_BASE_HANDLERS.elttype(expr);
13848
+ const comp = parseSetComprehension(expr.ops);
13849
+ if (comp === null) return SET_BASE_HANDLERS.elttype(expr);
13850
+ const elements = enumerateSetComprehension(comp);
13851
+ if (elements === void 0 || elements.length === 0) return "unknown";
13852
+ return widen(...elements.map((op) => op.type.type));
13853
+ }
13090
13854
  }
13091
13855
  },
13092
13856
  Length: {
@@ -13186,7 +13950,12 @@ var COLLECTIONS_LIBRARY = {
13186
13950
  },
13187
13951
  contains: (expr, target) => {
13188
13952
  const t = target.re;
13953
+ if (Number.isNaN(t))
13954
+ return typeMembership(target, "number") === false ? false : void 0;
13955
+ if (target.im !== 0) return false;
13189
13956
  if (!isFinite(t)) return false;
13957
+ if (isFunction2(expr) && expr.ops.some((op) => Number.isNaN(op.re)))
13958
+ return void 0;
13190
13959
  const [lower, upper, step] = range(expr);
13191
13960
  if (step === 0) return false;
13192
13961
  if (step > 0) {
@@ -13262,13 +14031,23 @@ var COLLECTIONS_LIBRARY = {
13262
14031
  signature: "(number, number) -> set<real>",
13263
14032
  canonical: ([lo, hi], { engine }) => {
13264
14033
  if (!lo || !hi) return null;
14034
+ const unwrap2 = (op) => {
14035
+ if (isFunction2(op, "Open")) return [op.op1, true];
14036
+ if (isFunction2(op, "Closed")) return [op.op1, false];
14037
+ return [op, false];
14038
+ };
14039
+ const [loVal, loOpen] = unwrap2(lo);
14040
+ const [hiVal, hiOpen] = unwrap2(hi);
13265
14041
  const [lower, upper] = checkTypes(
13266
14042
  engine,
13267
- [lo.canonical, hi.canonical],
14043
+ [loVal.canonical, hiVal.canonical],
13268
14044
  ["number", "number"]
13269
14045
  );
13270
14046
  if (!lower.isValid || !upper.isValid) return null;
13271
- return engine._fn("Interval", [lower, upper]);
14047
+ return engine._fn("Interval", [
14048
+ loOpen ? engine._fn("Open", [lower]) : lower,
14049
+ hiOpen ? engine._fn("Open", [upper]) : upper
14050
+ ]);
13272
14051
  },
13273
14052
  eq: (a, b) => {
13274
14053
  const intervalA = interval(a);
@@ -13303,19 +14082,32 @@ var COLLECTIONS_LIBRARY = {
13303
14082
  },
13304
14083
  isEmpty: (_expr) => {
13305
14084
  const int = interval(_expr);
13306
- if (!int) return false;
14085
+ if (!int) return void 0;
13307
14086
  if (int.openStart && int.start === int.end) return true;
13308
14087
  if (int.openEnd && int.start === int.end) return true;
13309
14088
  if (int.openStart && int.openEnd) return false;
13310
14089
  return int.start >= int.end;
13311
14090
  },
13312
14091
  isFinite: (_expr) => false,
14092
+ // Three-valued membership: `true` only when both bound checks are
14093
+ // entailed, `false` when a bound check (or the type of the target)
14094
+ // refutes membership, `undefined` otherwise (e.g. symbolic target
14095
+ // with unknown bounds). Endpoints may be ±Infinity.
13313
14096
  contains: (expr, target) => {
13314
14097
  const int = interval(expr);
13315
- if (!int) return false;
13316
- if (int.openStart && target.isLessEqual(int.start)) return false;
13317
- if (int.openEnd && target.isGreaterEqual(int.end)) return false;
13318
- return target.isGreaterEqual(int.start) && target.isLessEqual(int.end);
14098
+ if (!int) return void 0;
14099
+ if (typeMembership(target, "number") === false) return false;
14100
+ const t = target.re;
14101
+ if (!Number.isNaN(t)) {
14102
+ if (target.im !== 0) return false;
14103
+ return intervalContains(int, t);
14104
+ }
14105
+ const aboveLower = int.openStart ? target.isGreater(int.start) : target.isGreaterEqual(int.start);
14106
+ if (aboveLower === false) return false;
14107
+ const belowUpper = int.openEnd ? target.isLess(int.end) : target.isLessEqual(int.end);
14108
+ if (belowUpper === false) return false;
14109
+ if (aboveLower === true && belowUpper === true) return true;
14110
+ return void 0;
13319
14111
  },
13320
14112
  eltsgn: (expr) => {
13321
14113
  const i = interval(expr);
@@ -13397,11 +14189,15 @@ var COLLECTIONS_LIBRARY = {
13397
14189
  };
13398
14190
  },
13399
14191
  contains: (expr, target) => {
13400
- if (!target.type.matches("finite_real")) return false;
13401
- if (!isFunction2(expr)) return false;
13402
14192
  const t = target.re;
14193
+ if (Number.isNaN(t))
14194
+ return typeMembership(target, "number") === false ? false : void 0;
14195
+ if (target.im !== 0) return false;
14196
+ if (!isFinite(t)) return false;
14197
+ if (!isFunction2(expr)) return void 0;
13403
14198
  const lower = expr.op1.re;
13404
14199
  const upper = expr.op2.re;
14200
+ if (Number.isNaN(lower) || Number.isNaN(upper)) return void 0;
13405
14201
  if (t < lower || t > upper) return false;
13406
14202
  let count = expr.op3.re;
13407
14203
  if (!isFinite(count)) count = DEFAULT_LINSPACE_COUNT;
@@ -13431,8 +14227,18 @@ var COLLECTIONS_LIBRARY = {
13431
14227
  description: ["Return the number of elements in the collection."],
13432
14228
  complexity: 8200,
13433
14229
  signature: "(collection) -> integer",
13434
- evaluate: ([xs], { engine }) => xs.isEmptyCollection ? engine.Zero : engine.number(xs.count),
13435
- sgn: ([xs]) => xs.isEmptyCollection ? "zero" : "positive"
14230
+ evaluate: ([xs], { engine }) => {
14231
+ if (xs.isEmptyCollection) return engine.Zero;
14232
+ const n = xs.count;
14233
+ if (n === void 0) return void 0;
14234
+ return engine.number(n);
14235
+ },
14236
+ sgn: ([xs]) => {
14237
+ const empty = xs.isEmptyCollection;
14238
+ if (empty === true) return "zero";
14239
+ if (empty === false) return "positive";
14240
+ return void 0;
14241
+ }
13436
14242
  },
13437
14243
  IsEmpty: {
13438
14244
  description: ["Return True if the collection is empty, False otherwise."],
@@ -13548,7 +14354,13 @@ var COLLECTIONS_LIBRARY = {
13548
14354
  },
13549
14355
  collection: {
13550
14356
  isLazy: (_expr) => true,
13551
- count: (_expr) => Infinity,
14357
+ count: (expr) => {
14358
+ if (!isFunction2(expr)) return void 0;
14359
+ if (!expr.op1.isFiniteCollection) return Infinity;
14360
+ let n = 0;
14361
+ for (const _ of expr.each()) n++;
14362
+ return n;
14363
+ },
13552
14364
  contains: (expr, target) => {
13553
14365
  if (!isFunction2(expr)) return false;
13554
14366
  if (!expr.contains(target)) return false;
@@ -13657,24 +14469,26 @@ var COLLECTIONS_LIBRARY = {
13657
14469
  type: (ops) => parseType(functionResult(ops[1].type.type) ?? "unknown"),
13658
14470
  evaluate: ([collection, fn, initial], { engine: ce }) => {
13659
14471
  if (!collection.isFiniteCollection) return void 0;
14472
+ const hasInitial = initial !== void 0;
13660
14473
  initial ??= ce.Nothing;
13661
14474
  if (initial.type.matches("real") && collection.type.matches(ce.type("collection<real>"))) {
13662
14475
  const compiled = ce._compile(fn);
13663
- if (compiled.calling !== "lambda" || !compiled.run) return void 0;
13664
- return run(
13665
- (function* () {
13666
- let accumulator = initial.re;
13667
- let first = true;
13668
- for (const item of collection.each()) {
13669
- if (first) accumulator = item.re;
13670
- else accumulator = compiled.run(accumulator, item.re);
13671
- first = false;
13672
- yield;
13673
- }
13674
- return ce.expr(accumulator);
13675
- })(),
13676
- ce._timeRemaining
13677
- );
14476
+ if (compiled.calling === "lambda" && compiled.run) {
14477
+ return run(
14478
+ (function* () {
14479
+ let accumulator = hasInitial ? initial.re : NaN;
14480
+ let first = true;
14481
+ for (const item of collection.each()) {
14482
+ if (first && !hasInitial) accumulator = item.re;
14483
+ else accumulator = compiled.run(accumulator, item.re);
14484
+ first = false;
14485
+ yield;
14486
+ }
14487
+ return ce.expr(accumulator);
14488
+ })(),
14489
+ ce._timeRemaining
14490
+ );
14491
+ }
13678
14492
  }
13679
14493
  const f = applicable(fn);
13680
14494
  return run(
@@ -13867,10 +14681,13 @@ var COLLECTIONS_LIBRARY = {
13867
14681
  const [xs, nExpr] = expr.ops;
13868
14682
  const n = toInteger(nExpr) ?? 0;
13869
14683
  if (n <= 0) return xs.each();
14684
+ const count = xs.count;
13870
14685
  let index = n + 1;
13871
14686
  return {
13872
14687
  next: () => {
13873
- const value = expr.op1.at(index++);
14688
+ if (count !== void 0 && index > count)
14689
+ return { value: void 0, done: true };
14690
+ const value = xs.at(index++);
13874
14691
  if (value === void 0) return { value: void 0, done: true };
13875
14692
  return { value, done: false };
13876
14693
  }
@@ -13881,7 +14698,13 @@ var COLLECTIONS_LIBRARY = {
13881
14698
  if (!isFunction2(expr)) return void 0;
13882
14699
  const [xs, nExpr] = expr.ops;
13883
14700
  const n = toInteger(nExpr) ?? 0;
13884
- if (n <= 0) return void 0;
14701
+ if (n <= 0) return xs.at(index);
14702
+ if (index < 0) {
14703
+ const count = xs.count;
14704
+ if (count !== void 0 && -index > count - n) return void 0;
14705
+ return xs.at(index);
14706
+ }
14707
+ if (index < 1) return void 0;
13885
14708
  return xs.at(index + n);
13886
14709
  }
13887
14710
  }
@@ -13963,11 +14786,15 @@ var COLLECTIONS_LIBRARY = {
13963
14786
  iterator: (expr) => {
13964
14787
  if (!isFunction2(expr))
13965
14788
  return { next: () => ({ value: void 0, done: true }) };
14789
+ const op1 = expr.op1;
14790
+ const count = op1.count;
14791
+ let index = 2;
13966
14792
  return {
13967
14793
  next: () => {
13968
- let index = 1;
13969
- const value = expr.op1.at(index > 0 ? index + 1 : index);
13970
- if (!value) return { value: void 0, done: true };
14794
+ if (count !== void 0 && index > count)
14795
+ return { value: void 0, done: true };
14796
+ const value = op1.at(index);
14797
+ if (value === void 0) return { value: void 0, done: true };
13971
14798
  index += 1;
13972
14799
  return { value, done: false };
13973
14800
  }
@@ -14046,12 +14873,17 @@ var COLLECTIONS_LIBRARY = {
14046
14873
  isLazy: (_expr) => true,
14047
14874
  count: (expr) => {
14048
14875
  if (!isFunction2(expr)) return void 0;
14049
- const start = toInteger(expr.op2) ?? 1;
14050
14876
  const count = expr.op1.count;
14051
14877
  if (count === void 0) return void 0;
14052
- const end = toInteger(expr.op3) ?? count;
14053
- if (start < 1) return Math.max(0, end + start - 1);
14054
- return Math.max(0, Math.min(end, count) - start + 1);
14878
+ let start = toInteger(expr.op2) ?? 1;
14879
+ if (start < 1) start = count + 1 + start;
14880
+ if (start < 1) start = 1;
14881
+ if (start > count) return 0;
14882
+ let end = toInteger(expr.op3) ?? count;
14883
+ if (end < 1) end = count + 1 + end;
14884
+ if (end < 1) end = 1;
14885
+ if (end > count) end = count;
14886
+ return Math.max(0, end - start + 1);
14055
14887
  },
14056
14888
  isFinite: (_expr) => true,
14057
14889
  at: (expr, index) => {
@@ -14067,6 +14899,11 @@ var COLLECTIONS_LIBRARY = {
14067
14899
  if (end < 1) end = count + 1 + end;
14068
14900
  if (end < 1) end = 1;
14069
14901
  if (end > count) end = count;
14902
+ const length = end - start + 1;
14903
+ if (length <= 0) return void 0;
14904
+ if (index < 0) index = length + 1 + index;
14905
+ if (index < 1 || index > length) return void 0;
14906
+ return expr.op1.at(start + index - 1);
14070
14907
  },
14071
14908
  iterator: (expr) => {
14072
14909
  if (!isFunction2(expr))
@@ -14330,7 +15167,7 @@ var COLLECTIONS_LIBRARY = {
14330
15167
  for (const item of xs.each()) {
14331
15168
  const pred = sym(f([item]));
14332
15169
  if (pred === "True") indices.push(ce.number(index));
14333
- if (pred !== "False")
15170
+ else if (pred !== "False")
14334
15171
  throw new Error(
14335
15172
  `Filter predicate must return "True" or "False". ${spellCheckMessage(
14336
15173
  fn
@@ -14579,11 +15416,25 @@ var COLLECTIONS_LIBRARY = {
14579
15416
  count: zipCount,
14580
15417
  isFinite: (expr) => {
14581
15418
  if (!isFunction2(expr)) return void 0;
14582
- return expr.ops.every((x) => x.isFiniteCollection);
15419
+ if (expr.nops === 0) return true;
15420
+ let anyUnknown = false;
15421
+ for (const x of expr.ops) {
15422
+ const f = x.isFiniteCollection;
15423
+ if (f === true) return true;
15424
+ if (f === void 0) anyUnknown = true;
15425
+ }
15426
+ return anyUnknown ? void 0 : false;
14583
15427
  },
14584
15428
  isEmpty: (expr) => {
14585
15429
  if (!isFunction2(expr)) return void 0;
14586
- return expr.nops === 0 || expr.ops.every((x) => x.isEmptyCollection);
15430
+ if (expr.nops === 0) return true;
15431
+ let anyUnknown = false;
15432
+ for (const x of expr.ops) {
15433
+ const e = x.isEmptyCollection;
15434
+ if (e === true) return true;
15435
+ if (e === void 0) anyUnknown = true;
15436
+ }
15437
+ return anyUnknown ? void 0 : false;
14587
15438
  },
14588
15439
  iterator: (expr) => {
14589
15440
  if (!isFunction2(expr))
@@ -14743,9 +15594,22 @@ var COLLECTIONS_LIBRARY = {
14743
15594
  signature: "(list) -> list",
14744
15595
  collection: {
14745
15596
  isLazy: (_expr) => true,
14746
- count: () => Infinity,
14747
- isEmpty: (expr) => expr.isEmptyCollection,
14748
- isFinite: (expr) => !expr.isEmptyCollection,
15597
+ // Cycling a non-empty collection is infinite; cycling an empty one is
15598
+ // empty. Inspect the *underlying* collection (`op1`) reading
15599
+ // `expr.isEmptyCollection`/`expr.isFiniteCollection` here would re-enter
15600
+ // these same handlers and recurse infinitely.
15601
+ count: (expr) => {
15602
+ if (!isFunction2(expr)) return void 0;
15603
+ return expr.op1.isEmptyCollection ? 0 : Infinity;
15604
+ },
15605
+ isEmpty: (expr) => {
15606
+ if (!isFunction2(expr)) return void 0;
15607
+ return expr.op1.isEmptyCollection;
15608
+ },
15609
+ isFinite: (expr) => {
15610
+ if (!isFunction2(expr)) return void 0;
15611
+ return expr.op1.isEmptyCollection;
15612
+ },
14749
15613
  contains: (expr, target) => {
14750
15614
  if (!isFunction2(expr)) return false;
14751
15615
  return expr.op1.contains(target) ?? false;
@@ -14759,7 +15623,7 @@ var COLLECTIONS_LIBRARY = {
14759
15623
  return { next: () => ({ value: void 0, done: true }) };
14760
15624
  return {
14761
15625
  next: () => {
14762
- const i = (index - 1 - 1) % l + 1;
15626
+ const i = (index - 1) % l + 1;
14763
15627
  const value = expr.op1.at(i);
14764
15628
  if (value === void 0) return { value: void 0, done: true };
14765
15629
  index += 1;
@@ -14881,7 +15745,7 @@ var COLLECTIONS_LIBRARY = {
14881
15745
  evaluate: (ops, { engine: ce }) => {
14882
15746
  const elements = [];
14883
15747
  for (const xs of ops) {
14884
- if (xs.isCollection) elements.push(xs);
15748
+ if (!xs.isCollection) elements.push(xs);
14885
15749
  else {
14886
15750
  if (!xs.isFiniteCollection) return void 0;
14887
15751
  elements.push(...Array.from(xs.each()));
@@ -14897,7 +15761,7 @@ var COLLECTIONS_LIBRARY = {
14897
15761
  evaluate: (ops, { engine: ce }) => {
14898
15762
  const elements = [];
14899
15763
  for (const xs of ops) {
14900
- if (xs.isCollection) elements.push(xs);
15764
+ if (!xs.isCollection) elements.push(xs);
14901
15765
  else {
14902
15766
  if (!xs.isFiniteCollection) return void 0;
14903
15767
  elements.push(...Array.from(xs.each()));
@@ -14990,11 +15854,129 @@ function canonicalList(ops, { engine: ce }) {
14990
15854
  return ce._fn("List", ops);
14991
15855
  }
14992
15856
  function canonicalSet(ops, { engine }) {
15857
+ ops = ops.map((op) => op.canonical);
15858
+ if (parseSetComprehension(ops) !== null) return engine._fn("Set", [...ops]);
14993
15859
  const set = [];
14994
15860
  const has = (x) => set.some((y) => y.isSame(x));
14995
15861
  for (const op of ops) if (!has(op)) set.push(op);
14996
15862
  return engine._fn("Set", set);
14997
15863
  }
15864
+ function parseSetComprehension(ops) {
15865
+ if (ops.length !== 2) return null;
15866
+ const [body, spec] = ops;
15867
+ const canon = (x) => x.isCanonical ? x : x.canonical;
15868
+ if (isFunction2(spec, "Element") && spec.nops >= 2) {
15869
+ if (!isSymbol2(spec.op1)) return null;
15870
+ const v = spec.op1.symbol;
15871
+ if (!body.has(v)) return null;
15872
+ const cond = spec.nops >= 3 && sym(spec.op3) !== "Nothing" ? spec.op3 : void 0;
15873
+ return { body, variable: v, domain: spec.op2, condition: cond };
15874
+ }
15875
+ if (isFunction2(spec, "Condition") && spec.nops >= 1) {
15876
+ const pred = spec.op1;
15877
+ if (isFunction2(body, "Element") && body.nops === 2 && isSymbol2(body.op1)) {
15878
+ return {
15879
+ body: body.op1,
15880
+ variable: body.op1.symbol,
15881
+ domain: canon(body.op2),
15882
+ condition: canon(pred)
15883
+ };
15884
+ }
15885
+ if (isFunction2(pred, "Element") && pred.nops === 2 && isSymbol2(pred.op1)) {
15886
+ const v = pred.op1.symbol;
15887
+ if (body.has(v))
15888
+ return {
15889
+ body,
15890
+ variable: v,
15891
+ domain: canon(pred.op2),
15892
+ condition: void 0
15893
+ };
15894
+ }
15895
+ if (isFunction2(pred, "And")) {
15896
+ const memberships = pred.ops.filter(
15897
+ (x) => isFunction2(x, "Element") && x.nops === 2 && isSymbol2(x.op1) && body.has(x.op1.symbol)
15898
+ );
15899
+ const membership = memberships.length === 1 ? memberships[0] : void 0;
15900
+ if (membership && isFunction2(membership, "Element") && isSymbol2(membership.op1)) {
15901
+ const rest = pred.ops.filter((x) => x !== membership).map(canon);
15902
+ const ce = body.engine;
15903
+ const cond = rest.length === 0 ? void 0 : rest.length === 1 ? rest[0] : ce._fn("And", rest);
15904
+ return {
15905
+ body,
15906
+ variable: membership.op1.symbol,
15907
+ domain: canon(membership.op2),
15908
+ condition: cond
15909
+ };
15910
+ }
15911
+ }
15912
+ return {
15913
+ body,
15914
+ variable: isSymbol2(body) ? body.symbol : void 0,
15915
+ domain: void 0,
15916
+ condition: pred
15917
+ };
15918
+ }
15919
+ return null;
15920
+ }
15921
+ function enumerateSetComprehension(comp) {
15922
+ const { body, variable, domain, condition } = comp;
15923
+ if (variable === void 0 || domain === void 0) return void 0;
15924
+ const ce = body.engine;
15925
+ const extract = (dom) => extractFiniteDomainWithReason(
15926
+ ce._fn("Element", [
15927
+ ce.symbol(variable),
15928
+ dom,
15929
+ ...condition ? [condition] : []
15930
+ ]),
15931
+ ce
15932
+ );
15933
+ let result = extract(domain);
15934
+ if (result.status !== "success") {
15935
+ const evaluatedDomain = domain.evaluate();
15936
+ if (!evaluatedDomain.isSame(domain)) result = extract(evaluatedDomain);
15937
+ }
15938
+ if (result.status !== "success") return void 0;
15939
+ const isIdentity = isSymbol2(body) && body.symbol === variable;
15940
+ const elements = [];
15941
+ for (const value of result.values) {
15942
+ const x = isIdentity ? value : body.subs({ [variable]: value }).evaluate();
15943
+ if (!elements.some((y) => y.isSame(x))) elements.push(x);
15944
+ }
15945
+ return elements;
15946
+ }
15947
+ function literalSetContains(ops, target) {
15948
+ let indeterminate = false;
15949
+ for (const op of ops) {
15950
+ if (target.isSame(op)) return true;
15951
+ if (isNumber(target) && isNumber(op)) {
15952
+ const eq2 = target.isEqual(op);
15953
+ if (eq2 === true) return true;
15954
+ if (eq2 !== false) indeterminate = true;
15955
+ } else if (isString(target) && isString(op)) {
15956
+ } else {
15957
+ indeterminate = true;
15958
+ }
15959
+ }
15960
+ return indeterminate ? void 0 : false;
15961
+ }
15962
+ function setComprehensionContains(comp, target) {
15963
+ const elements = enumerateSetComprehension(comp);
15964
+ if (elements !== void 0) return literalSetContains(elements, target);
15965
+ if (comp.domain !== void 0 && comp.variable !== void 0 && isSymbol2(comp.body) && comp.body.symbol === comp.variable) {
15966
+ const inDomain = comp.domain.contains(target);
15967
+ if (inDomain === false) return false;
15968
+ let condition = true;
15969
+ if (comp.condition !== void 0) {
15970
+ if (isNumber(target) || isString(target)) {
15971
+ const result = comp.condition.subs({ [comp.variable]: target }).evaluate();
15972
+ condition = sym(result) === "True" ? true : sym(result) === "False" ? false : void 0;
15973
+ } else condition = void 0;
15974
+ }
15975
+ if (condition === false) return false;
15976
+ if (inDomain === true && condition === true) return true;
15977
+ }
15978
+ return void 0;
15979
+ }
14998
15980
  function tally(collection) {
14999
15981
  const values = [];
15000
15982
  const counts = [];
@@ -15234,7 +16216,11 @@ var BaseCompiler = class _BaseCompiler {
15234
16216
  op[1]
15235
16217
  )}`;
15236
16218
  } else {
15237
- resultStr = args.map((arg) => _BaseCompiler.compile(arg, target, op[1])).join(` ${op[0]} `);
16219
+ const rightAssoc = h === "Power";
16220
+ resultStr = args.map((arg, i) => {
16221
+ const operandPrec = rightAssoc && i < args.length - 1 ? op[1] + 1 : op[1];
16222
+ return _BaseCompiler.compile(arg, target, operandPrec);
16223
+ }).join(` ${op[0]} `);
15238
16224
  }
15239
16225
  return op[1] < prec ? `(${resultStr})` : resultStr;
15240
16226
  }
@@ -15927,6 +16913,17 @@ function compile(expr, options) {
15927
16913
  `Compilation fallback for "${expr.operator}" (target: ${options?.to ?? "javascript"}): ${e.message}`
15928
16914
  );
15929
16915
  const ce = expr.engine;
16916
+ const target = options?.to ?? "javascript";
16917
+ if (isFunction2(expr, "Function")) {
16918
+ const lambdaRun = ((...args) => ce.function("Apply", [expr, ...args.map((a) => ce.box(a))]).evaluate().re);
16919
+ return {
16920
+ target,
16921
+ success: false,
16922
+ code: "",
16923
+ calling: "lambda",
16924
+ run: lambdaRun
16925
+ };
16926
+ }
15930
16927
  const fallbackRun = ((vars) => {
15931
16928
  ce.pushScope();
15932
16929
  try {
@@ -15939,7 +16936,7 @@ function compile(expr, options) {
15939
16936
  }
15940
16937
  });
15941
16938
  return {
15942
- target: options?.to ?? "javascript",
16939
+ target,
15943
16940
  success: false,
15944
16941
  code: "",
15945
16942
  calling: "expression",
@@ -15993,6 +16990,11 @@ function foldTerms(terms, identity, op) {
15993
16990
  if (symbolic.length === 1) return symbolic[0];
15994
16991
  return symbolic.join(op === "+" ? " + " : " * ");
15995
16992
  }
16993
+ function parenthesizeFactor(expr, code) {
16994
+ if (isFunction2(expr, "Add") || isFunction2(expr, "Subtract"))
16995
+ return `(${code})`;
16996
+ return code;
16997
+ }
15996
16998
  function tryGetComplexParts(expr, compile2) {
15997
16999
  if (isSymbol2(expr, "ImaginaryUnit")) {
15998
17000
  return { re: null, im: "1.0" };
@@ -16017,7 +17019,9 @@ function tryGetComplexParts(expr, compile2) {
16017
17019
  if (remaining.length === 0) {
16018
17020
  return { re: null, im: formatFloat(iScale) };
16019
17021
  }
16020
- const compiledFactors = remaining.map((r) => compile2(r));
17022
+ const compiledFactors = remaining.map(
17023
+ (r) => parenthesizeFactor(r, compile2(r))
17024
+ );
16021
17025
  if (iScale !== 1) compiledFactors.unshift(formatFloat(iScale));
16022
17026
  const imCode = foldTerms(compiledFactors, "1.0", "*");
16023
17027
  return { re: null, im: imCode };
@@ -19534,9 +20538,14 @@ var lanczos_7_c = [
19534
20538
  ];
19535
20539
  function gammaln(z) {
19536
20540
  if (z < 0) return NaN;
20541
+ let shift = 0;
20542
+ while (z < 10) {
20543
+ shift += Math.log(z);
20544
+ z += 1;
20545
+ }
19537
20546
  const pi = Math.PI;
19538
20547
  const z3 = z * z * z;
19539
- return z * Math.log(z) - z - 0.5 * Math.log(z) + 0.5 * Math.log(2 * pi) + 1 / (12 * z) - 1 / (360 * z3) + 1 / (1260 * z3 * z * z);
20548
+ return z * Math.log(z) - z - 0.5 * Math.log(z) + 0.5 * Math.log(2 * pi) + 1 / (12 * z) - 1 / (360 * z3) + 1 / (1260 * z3 * z * z) - shift;
19540
20549
  }
19541
20550
  function gamma(z) {
19542
20551
  if (z < 0.5) return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
@@ -19547,31 +20556,62 @@ function gamma(z) {
19547
20556
  const t = z + gammaG + 0.5;
19548
20557
  return Math.sqrt(2 * Math.PI) * Math.pow(t, z + 0.5) * Math.exp(-t) * x;
19549
20558
  }
20559
+ function erfInvApprox(x) {
20560
+ const a = 0.147;
20561
+ const ln1mx2 = Math.log(1 - x * x);
20562
+ const b = 2 / (Math.PI * a) + ln1mx2 / 2;
20563
+ return Math.sign(x) * Math.sqrt(Math.sqrt(b * b - ln1mx2 / a) - b);
20564
+ }
19550
20565
  function erfInv(x) {
19551
- const pi = Math.PI;
19552
- const pi2 = pi * pi;
19553
- const pi3 = pi2 * pi;
19554
- const x2 = x * x;
19555
- const x3 = x * x2;
19556
- const x5 = x3 * x2;
19557
- const x7 = x5 * x2;
19558
- return Math.sqrt(pi) / 2 * (x + pi / 12 * x3 + 7 * pi2 / 480 * x5 + 127 * pi3 / 40320 * x7 + 4369 * pi2 * pi2 / 5806080 * x7 * x2 + 34807 * pi3 * pi2 / 182476800 * x7 * x2 * x2);
20566
+ if (Number.isNaN(x) || x < -1 || x > 1) return NaN;
20567
+ if (x === 0) return 0;
20568
+ if (x === 1) return Infinity;
20569
+ if (x === -1) return -Infinity;
20570
+ const sign2 = x < 0 ? -1 : 1;
20571
+ const ax = Math.abs(x);
20572
+ let y = erfInvApprox(ax);
20573
+ const c = Math.sqrt(Math.PI) / 2;
20574
+ for (let i = 0; i < 4; i++) y -= (erf(y) - ax) * c * Math.exp(y * y);
20575
+ return sign2 * y;
19559
20576
  }
19560
20577
  function erfc(x) {
19561
- return 1 - erf(x);
20578
+ if (Number.isNaN(x)) return NaN;
20579
+ if (!Number.isFinite(x)) return x > 0 ? 0 : 2;
20580
+ if (x < 0) return 2 - erfc(-x);
20581
+ if (x < 2) return 1 - erf(x);
20582
+ const tiny = 1e-300;
20583
+ let f = x === 0 ? tiny : x;
20584
+ let c = f;
20585
+ let d = 0;
20586
+ for (let k = 1; k <= 500; k++) {
20587
+ const a = k / 2;
20588
+ d = x + a * d;
20589
+ if (d === 0) d = tiny;
20590
+ d = 1 / d;
20591
+ c = x + a / c;
20592
+ if (c === 0) c = tiny;
20593
+ const delta = c * d;
20594
+ f *= delta;
20595
+ if (Math.abs(delta - 1) < 1e-17) break;
20596
+ }
20597
+ return Math.exp(-x * x) / (Math.sqrt(Math.PI) * f);
19562
20598
  }
19563
20599
  function erf(x) {
19564
- const a1 = 0.254829592;
19565
- const a2 = -0.284496736;
19566
- const a3 = 1.421413741;
19567
- const a4 = -1.453152027;
19568
- const a5 = 1.061405429;
19569
- const p = 0.3275911;
20600
+ if (Number.isNaN(x)) return NaN;
20601
+ if (x === 0) return 0;
20602
+ if (!Number.isFinite(x)) return x > 0 ? 1 : -1;
19570
20603
  const sign2 = x < 0 ? -1 : 1;
19571
- x = Math.abs(x);
19572
- const t = 1 / (1 + p * x);
19573
- const y = ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t;
19574
- return sign2 * (1 - y * Math.exp(-x * x));
20604
+ const ax = Math.abs(x);
20605
+ if (ax >= 6) return sign2;
20606
+ const x2 = ax * ax;
20607
+ let term = ax;
20608
+ let sum = ax;
20609
+ for (let n = 1; n < 200; n++) {
20610
+ term *= 2 * x2 / (2 * n + 1);
20611
+ sum += term;
20612
+ if (term < sum * 1e-18) break;
20613
+ }
20614
+ return sign2 * (2 / Math.sqrt(Math.PI)) * Math.exp(-x2) * sum;
19575
20615
  }
19576
20616
  var EULER_MASCHERONI = 0.5772156649015329;
19577
20617
  var BERNOULLI_2K = [
@@ -20157,7 +21197,7 @@ function fresnelS(x) {
20157
21197
  const t = x2 * x2;
20158
21198
  return sign2 * x * x2 * polevl(t, SN) / polevl(t, SD);
20159
21199
  }
20160
- if (x < 36) {
21200
+ if (x < 36974) {
20161
21201
  const x2 = x * x;
20162
21202
  const t = Math.PI * x2;
20163
21203
  const u = 1 / (t * t);
@@ -20182,7 +21222,7 @@ function fresnelC(x) {
20182
21222
  const t = x2 * x2;
20183
21223
  return sign2 * x * polevl(t, CN) / polevl(t, CD);
20184
21224
  }
20185
- if (x < 36) {
21225
+ if (x < 36974) {
20186
21226
  const x2 = x * x;
20187
21227
  const t = Math.PI * x2;
20188
21228
  const u = 1 / (t * t);
@@ -20273,6 +21313,7 @@ function populationStandardDeviation(values) {
20273
21313
  function kurtosis(values) {
20274
21314
  let sum = 0;
20275
21315
  let sum2 = 0;
21316
+ let sum3 = 0;
20276
21317
  let sum4 = 0;
20277
21318
  let count = 0;
20278
21319
  for (const op of values) {
@@ -20280,12 +21321,16 @@ function kurtosis(values) {
20280
21321
  if (!Number.isFinite(v)) return NaN;
20281
21322
  sum += v;
20282
21323
  sum2 += v * v;
21324
+ sum3 += v * v * v;
20283
21325
  sum4 += v * v * v * v;
20284
21326
  count++;
20285
21327
  }
20286
21328
  if (count === 0) return NaN;
20287
- const s2 = (sum2 - sum * sum / count) / (count - 1);
20288
- return (sum4 - 4 * sum * sum2 / count + 6 * sum * sum * sum / count / count - 3 * sum * sum * sum * sum / count / count / count) / (s2 * s2);
21329
+ const n = count;
21330
+ const m = sum / n;
21331
+ const m2 = (sum2 - sum * sum / n) / n;
21332
+ const m4 = (sum4 - 4 * m * sum3 + 6 * m * m * sum2 - 4 * m * m * m * sum + n * m * m * m * m) / n;
21333
+ return m4 / (m2 * m2);
20289
21334
  }
20290
21335
  function skewness(values) {
20291
21336
  let sum = 0;
@@ -20301,9 +21346,11 @@ function skewness(values) {
20301
21346
  count++;
20302
21347
  }
20303
21348
  if (count === 0) return NaN;
20304
- const s2 = (sum2 - sum * sum / count) / (count - 1);
20305
- const s3 = (sum3 - sum2 * sum / count) / (count - 1);
20306
- return s3 / Math.pow(s2, 3 / 2) * Math.sqrt(count * 1);
21349
+ const n = count;
21350
+ const m = sum / n;
21351
+ const m2 = (sum2 - sum * sum / n) / n;
21352
+ const m3 = (sum3 - 3 * m * sum2 + 3 * m * m * sum - n * m * m * m) / n;
21353
+ return m3 / Math.pow(m2, 3 / 2);
20307
21354
  }
20308
21355
  function mode(values) {
20309
21356
  const counts = {};
@@ -20330,11 +21377,8 @@ function quartiles(values) {
20330
21377
  return [q1, q2, q3];
20331
21378
  }
20332
21379
  function interquartileRange(values) {
20333
- const sorted = [...values].sort((a, b) => a - b);
20334
- const mid = Math.floor(sorted.length / 2);
20335
- const lower = sorted.slice(0, mid);
20336
- const upper = sorted.slice(mid + 1);
20337
- return median(upper) - median(lower);
21380
+ const [q1, , q3] = quartiles(values);
21381
+ return q3 - q1;
20338
21382
  }
20339
21383
 
20340
21384
  // src/compute-engine/numerics/monte-carlo.ts
@@ -20665,7 +21709,7 @@ var JAVASCRIPT_FUNCTIONS = {
20665
21709
  if (parseFloat(step) === 1) {
20666
21710
  const fStop = parseFloat(stop);
20667
21711
  const fStart = parseFloat(start);
20668
- if (fStop !== null && fStart !== null) {
21712
+ if (!isNaN(fStop) && !isNaN(fStart)) {
20669
21713
  if (fStop - fStart < 50) {
20670
21714
  return `[${Array.from(
20671
21715
  { length: fStop - fStart + 1 },
@@ -20676,9 +21720,9 @@ var JAVASCRIPT_FUNCTIONS = {
20676
21720
  }, (_, i) => ${start} + i)`;
20677
21721
  }
20678
21722
  return `Array.from({length: ${stop} - ${start} + 1
20679
- }, (_, i) => ${start} + i)`;
21723
+ }, (_e, i) => ${start} + i)`;
20680
21724
  }
20681
- return `Array.from({length: Math.floor((${stop} - ${start}) / ${step}) + 1}, (_, i) => ${start} + i * ${step})`;
21725
+ return `Array.from({length: Math.floor((${stop} - ${start}) / ${step}) + 1}, (_e, i) => ${start} + i * ${step})`;
20682
21726
  },
20683
21727
  Root: ([arg, exp3], compile2) => {
20684
21728
  if (arg === null) throw new Error("Root: no argument");
@@ -21835,6 +22879,14 @@ function gpuVec2(target) {
21835
22879
  function gpuVec3(target) {
21836
22880
  return target?.language === "wgsl" ? "vec3f" : "vec3";
21837
22881
  }
22882
+ function gpuNaN(target) {
22883
+ return target?.language === "wgsl" ? "bitcast<f32>(0x7fc00000u)" : "(0.0 / 0.0)";
22884
+ }
22885
+ function gpuConditional(cond, whenTrue, whenFalse, target) {
22886
+ if (target?.language === "wgsl")
22887
+ return `select(${whenFalse}, ${whenTrue}, ${cond})`;
22888
+ return `((${cond}) ? (${whenTrue}) : (${whenFalse}))`;
22889
+ }
21838
22890
  function readStringLiteral(expr) {
21839
22891
  if (!isString(expr)) return null;
21840
22892
  return expr.string?.toLowerCase() ?? null;
@@ -21952,7 +23004,7 @@ var GPU_FUNCTIONS = {
21952
23004
  const realFactors = args.filter((_, i) => i !== iIndex);
21953
23005
  const v2 = gpuVec2(target);
21954
23006
  if (realFactors.length === 0) return `${v2}(0.0, ${formatFloat(iScale)})`;
21955
- const factors = realFactors.map((f) => compile2(f));
23007
+ const factors = realFactors.map((f) => parenthesizeFactor(f, compile2(f)));
21956
23008
  if (iScale !== 1) factors.unshift(formatFloat(iScale));
21957
23009
  const imCode = foldTerms(factors, "1.0", "*");
21958
23010
  return `${v2}(0.0, ${imCode})`;
@@ -21961,7 +23013,7 @@ var GPU_FUNCTIONS = {
21961
23013
  const complexCodes = [];
21962
23014
  for (const a of args) {
21963
23015
  if (BaseCompiler.isComplexValued(a)) complexCodes.push(compile2(a));
21964
- else realCodes.push(compile2(a));
23016
+ else realCodes.push(parenthesizeFactor(a, compile2(a)));
21965
23017
  }
21966
23018
  const scalarCode = foldTerms(realCodes, "1.0", "*");
21967
23019
  let result = complexCodes[0];
@@ -22039,7 +23091,9 @@ var GPU_FUNCTIONS = {
22039
23091
  return `_gpu_ccos(${compile2(args[0])})`;
22040
23092
  return `cos(${compile2(args[0])})`;
22041
23093
  },
22042
- Degrees: "degrees",
23094
+ // CE's `Degrees` converts degrees→radians (Degrees(180) = π), which is
23095
+ // GLSL's `radians()`. GLSL's `degrees()` is the inverse (rad→deg).
23096
+ Degrees: "radians",
22043
23097
  Exp: (args, compile2) => {
22044
23098
  if (BaseCompiler.isComplexValued(args[0]))
22045
23099
  return `_gpu_cexp(${compile2(args[0])})`;
@@ -22068,6 +23122,43 @@ var GPU_FUNCTIONS = {
22068
23122
  Max: "max",
22069
23123
  Min: "min",
22070
23124
  Mix: "mix",
23125
+ // Control-flow forms — the base compiler's default emits a JS ternary and a
23126
+ // bare `NaN`, neither of which is valid GPU code (WGSL has no `?:`, and no
23127
+ // shader language has a `NaN` identifier). Emit `select(...)` for WGSL and a
23128
+ // language-appropriate NaN.
23129
+ If: (args, compile2, target) => {
23130
+ if (args.length !== 3) throw new Error("If: wrong number of arguments");
23131
+ return gpuConditional(
23132
+ compile2(args[0]),
23133
+ compile2(args[1]),
23134
+ compile2(args[2]),
23135
+ target
23136
+ );
23137
+ },
23138
+ When: (args, compile2, target) => {
23139
+ if (args.length !== 2)
23140
+ throw new Error("When: expected exactly 2 arguments (expr, cond)");
23141
+ if (isSymbol2(args[1], "True")) return `(${compile2(args[0])})`;
23142
+ if (isSymbol2(args[1], "False")) return gpuNaN(target);
23143
+ return gpuConditional(
23144
+ compile2(args[1]),
23145
+ compile2(args[0]),
23146
+ gpuNaN(target),
23147
+ target
23148
+ );
23149
+ },
23150
+ Which: (args, compile2, target) => {
23151
+ if (args.length < 2 || args.length % 2 !== 0)
23152
+ throw new Error("Which: expected condition/value pairs");
23153
+ const build = (i) => {
23154
+ if (i >= args.length) return gpuNaN(target);
23155
+ const cond = args[i];
23156
+ const val = args[i + 1];
23157
+ if (isSymbol2(cond, "True")) return `(${compile2(val)})`;
23158
+ return gpuConditional(compile2(cond), compile2(val), build(i + 2), target);
23159
+ };
23160
+ return build(0);
23161
+ },
22071
23162
  Power: (args, compile2, target) => {
22072
23163
  const base = args[0];
22073
23164
  const exp3 = args[1];
@@ -22755,7 +23846,7 @@ function compileGPUMatrix(args, compile2, vecFn, matFn, arrayFn) {
22755
23846
  }
22756
23847
  return compile2(body);
22757
23848
  }
22758
- var GPU_GAMMA_PREAMBLE = `
23849
+ var GPU_GAMMA_PREAMBLE_GLSL = `
22759
23850
  float _gpu_gamma(float z) {
22760
23851
  const float PI = 3.14159265358979;
22761
23852
  // For z < 0.5, use reflection formula with inlined Lanczos (non-recursive)
@@ -22787,7 +23878,37 @@ float _gpu_gammaln(float z) {
22787
23878
  + 1.0 / (1260.0 * z3 * z * z);
22788
23879
  }
22789
23880
  `;
22790
- var GPU_ERF_PREAMBLE = `
23881
+ var GPU_GAMMA_PREAMBLE_WGSL = `
23882
+ fn _gpu_gamma(z: f32) -> f32 {
23883
+ let PI = 3.14159265358979;
23884
+ var w = z;
23885
+ if (z < 0.5) { w = 1.0 - z; }
23886
+ w = w - 1.0;
23887
+ var x = 0.99999999999980993;
23888
+ x = x + 676.5203681218851 / (w + 1.0);
23889
+ x = x + -1259.1392167224028 / (w + 2.0);
23890
+ x = x + 771.32342877765313 / (w + 3.0);
23891
+ x = x + -176.61502916214059 / (w + 4.0);
23892
+ x = x + 12.507343278686905 / (w + 5.0);
23893
+ x = x + -0.13857109526572012 / (w + 6.0);
23894
+ x = x + 9.9843695780195716e-6 / (w + 7.0);
23895
+ x = x + 1.5056327351493116e-7 / (w + 8.0);
23896
+ let t = w + 7.5;
23897
+ let g = sqrt(2.0 * PI) * pow(t, w + 0.5) * exp(-t) * x;
23898
+ if (z < 0.5) { return PI / (sin(PI * z) * g); }
23899
+ return g;
23900
+ }
23901
+
23902
+ fn _gpu_gammaln(z: f32) -> f32 {
23903
+ let z3 = z * z * z;
23904
+ return z * log(z) - z - 0.5 * log(z)
23905
+ + 0.5 * log(2.0 * 3.14159265358979)
23906
+ + 1.0 / (12.0 * z)
23907
+ - 1.0 / (360.0 * z3)
23908
+ + 1.0 / (1260.0 * z3 * z * z);
23909
+ }
23910
+ `;
23911
+ var GPU_ERF_PREAMBLE_GLSL = `
22791
23912
  float _gpu_erf(float x) {
22792
23913
  float ax = abs(x);
22793
23914
  float t = 1.0 / (1.0 + 0.3275911 * ax);
@@ -22806,6 +23927,26 @@ float _gpu_erfinv(float x) {
22806
23927
  return sqrt(pi) * 0.5 * (x + (pi / 12.0) * x3 + (7.0 * pi * pi / 480.0) * x5 + (127.0 * pi * pi * pi / 40320.0) * x7 + (4369.0 * pi * pi * pi * pi / 5806080.0) * x9);
22807
23928
  }
22808
23929
  `;
23930
+ var GPU_ERF_PREAMBLE_WGSL = `
23931
+ fn _gpu_erf(x: f32) -> f32 {
23932
+ let ax = abs(x);
23933
+ let t = 1.0 / (1.0 + 0.3275911 * ax);
23934
+ let y = ((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t - 0.284496736) * t + 0.254829592) * t;
23935
+ let result = 1.0 - y * exp(-ax * ax);
23936
+ if (x < 0.0) { return -result; }
23937
+ return result;
23938
+ }
23939
+
23940
+ fn _gpu_erfinv(x: f32) -> f32 {
23941
+ let pi = 3.14159265358979;
23942
+ let x2 = x * x;
23943
+ let x3 = x * x2;
23944
+ let x5 = x3 * x2;
23945
+ let x7 = x5 * x2;
23946
+ let x9 = x7 * x2;
23947
+ return sqrt(pi) * 0.5 * (x + (pi / 12.0) * x3 + (7.0 * pi * pi / 480.0) * x5 + (127.0 * pi * pi * pi / 40320.0) * x7 + (4369.0 * pi * pi * pi * pi / 5806080.0) * x9);
23948
+ }
23949
+ `;
22809
23950
  var GPU_HEAVISIDE_PREAMBLE_GLSL = `
22810
23951
  float _gpu_heaviside(float x) {
22811
23952
  if (x < 0.0) return 0.0;
@@ -24185,8 +25326,10 @@ var GPUShaderTarget = class {
24185
25326
  };
24186
25327
  let preamble = "";
24187
25328
  preamble += buildComplexPreamble(code, this.languageId);
24188
- if (code.includes("_gpu_gamma")) preamble += GPU_GAMMA_PREAMBLE;
24189
- if (code.includes("_gpu_erf")) preamble += GPU_ERF_PREAMBLE;
25329
+ if (code.includes("_gpu_gamma"))
25330
+ preamble += this.languageId === "wgsl" ? GPU_GAMMA_PREAMBLE_WGSL : GPU_GAMMA_PREAMBLE_GLSL;
25331
+ if (code.includes("_gpu_erf"))
25332
+ preamble += this.languageId === "wgsl" ? GPU_ERF_PREAMBLE_WGSL : GPU_ERF_PREAMBLE_GLSL;
24190
25333
  if (code.includes("_gpu_heaviside"))
24191
25334
  preamble += this.languageId === "wgsl" ? GPU_HEAVISIDE_PREAMBLE_WGSL : GPU_HEAVISIDE_PREAMBLE_GLSL;
24192
25335
  if (code.includes("_gpu_sinc"))
@@ -24972,9 +26115,18 @@ function negate(x) {
24972
26115
  return ok({ lo: -xVal.hi, hi: -xVal.lo });
24973
26116
  }
24974
26117
  function _mul(a, b) {
24975
- const products = [a.lo * b.lo, a.lo * b.hi, a.hi * b.lo, a.hi * b.hi];
26118
+ const products = [
26119
+ _prod(a.lo, b.lo),
26120
+ _prod(a.lo, b.hi),
26121
+ _prod(a.hi, b.lo),
26122
+ _prod(a.hi, b.hi)
26123
+ ];
24976
26124
  return { lo: Math.min(...products), hi: Math.max(...products) };
24977
26125
  }
26126
+ function _prod(x, y) {
26127
+ if (x === 0 || y === 0) return 0;
26128
+ return x * y;
26129
+ }
24978
26130
  function mul3(a, b) {
24979
26131
  const unwrapped = unwrapOrPropagate(a, b);
24980
26132
  if (!Array.isArray(unwrapped)) return unwrapped;
@@ -25308,6 +26460,7 @@ function mod(a, b) {
25308
26460
  const period = Math.abs(
25309
26461
  bVal.lo === bVal.hi ? bVal.lo : Math.max(Math.abs(bVal.lo), Math.abs(bVal.hi))
25310
26462
  );
26463
+ const divisorNegative = bVal.hi < 0;
25311
26464
  const flo = Math.floor(aVal.lo / period);
25312
26465
  const fhi = Math.floor(aVal.hi / period);
25313
26466
  if (flo !== fhi) {
@@ -25315,6 +26468,11 @@ function mod(a, b) {
25315
26468
  }
25316
26469
  const modLo = aVal.lo - period * flo;
25317
26470
  const modHi = aVal.hi - period * flo;
26471
+ if (divisorNegative) {
26472
+ if (modLo === 0)
26473
+ return { kind: "singular", at: aVal.lo, continuity: "right" };
26474
+ return ok({ lo: modLo - period, hi: modHi - period });
26475
+ }
25318
26476
  return ok({ lo: Math.min(modLo, modHi), hi: Math.max(modLo, modHi) });
25319
26477
  }
25320
26478
  function remainder(a, b) {
@@ -25346,6 +26504,23 @@ function gamma2(x) {
25346
26504
  const [xVal] = unwrapped;
25347
26505
  return _gamma(xVal);
25348
26506
  }
26507
+ var GAMMA_NEG_EXTREMA_X = [
26508
+ -0.504083008264455,
26509
+ -1.573498473162391,
26510
+ -2.610720868444145,
26511
+ -3.635293366436901,
26512
+ -4.653163765628266,
26513
+ -5.667162441556885,
26514
+ -6.678418213073426,
26515
+ -7.687788325031709,
26516
+ -8.695764163640956,
26517
+ -9.702672540001863
26518
+ ];
26519
+ function gammaNegStripExtremum(lo) {
26520
+ const n = Math.floor(lo);
26521
+ const idx = -n - 1;
26522
+ return idx >= 0 && idx < GAMMA_NEG_EXTREMA_X.length ? GAMMA_NEG_EXTREMA_X[idx] : null;
26523
+ }
25349
26524
  function _gamma(x) {
25350
26525
  if (x.hi >= 0 && x.lo <= 0) {
25351
26526
  return { kind: "singular", at: 0 };
@@ -25358,7 +26533,21 @@ function _gamma(x) {
25358
26533
  }
25359
26534
  const gLo = gamma(x.lo);
25360
26535
  const gHi = gamma(x.hi);
25361
- return ok({ lo: Math.min(gLo, gHi), hi: Math.max(gLo, gHi) });
26536
+ let lo = Math.min(gLo, gHi);
26537
+ let hi = Math.max(gLo, gHi);
26538
+ const xStar = gammaNegStripExtremum(x.lo);
26539
+ if (xStar !== null) {
26540
+ if (xStar >= x.lo && xStar <= x.hi) {
26541
+ const g = gamma(xStar);
26542
+ lo = Math.min(lo, g);
26543
+ hi = Math.max(hi, g);
26544
+ }
26545
+ } else {
26546
+ const stripEven = Math.floor(x.lo) % 2 === 0;
26547
+ if (stripEven) lo = Math.min(lo, 0);
26548
+ else hi = Math.max(hi, 0);
26549
+ }
26550
+ return ok({ lo, hi });
25362
26551
  }
25363
26552
  if (x.lo >= GAMMA_MIN_X) {
25364
26553
  return ok({ lo: gamma(x.lo), hi: gamma(x.hi) });
@@ -25389,7 +26578,15 @@ function _gammaln(x) {
25389
26578
  }
25390
26579
  const gLo = gammaln(x.lo);
25391
26580
  const gHi = gammaln(x.hi);
25392
- return ok({ lo: Math.min(gLo, gHi), hi: Math.max(gLo, gHi) });
26581
+ let lo = Math.min(gLo, gHi);
26582
+ const hi = Math.max(gLo, gHi);
26583
+ const xStar = gammaNegStripExtremum(x.lo);
26584
+ if (xStar !== null) {
26585
+ if (xStar >= x.lo && xStar <= x.hi) lo = Math.min(lo, gammaln(xStar));
26586
+ } else {
26587
+ lo = -Infinity;
26588
+ }
26589
+ return ok({ lo, hi });
25393
26590
  }
25394
26591
  return ok({ lo: gammaln(x.lo), hi: gammaln(x.hi) });
25395
26592
  }
@@ -25415,6 +26612,33 @@ function factorial22(x) {
25415
26612
  return ok({ lo: Math.min(fLo, fHi), hi: Math.max(fLo, fHi) });
25416
26613
  return ok({ lo: fLo, hi: fHi });
25417
26614
  }
26615
+ var MAX_INT_ENUM_POINTS = 4096;
26616
+ function integerPoints(lo, hi, cap) {
26617
+ const a = Math.round(lo);
26618
+ const b = Math.round(hi);
26619
+ if (!Number.isFinite(a) || !Number.isFinite(b)) return null;
26620
+ if (b - a + 1 > cap) return null;
26621
+ const out = [];
26622
+ for (let i = a; i <= b; i++) out.push(i);
26623
+ return out;
26624
+ }
26625
+ function enumerateInteger2(a, b, f) {
26626
+ const xs = integerPoints(a.lo, a.hi, MAX_INT_ENUM_POINTS);
26627
+ const ys = integerPoints(b.lo, b.hi, MAX_INT_ENUM_POINTS);
26628
+ if (!xs || !ys || xs.length * ys.length > MAX_INT_ENUM_POINTS) return null;
26629
+ let lo = Infinity;
26630
+ let hi = -Infinity;
26631
+ for (const x of xs)
26632
+ for (const y of ys) {
26633
+ const v = f(x, y);
26634
+ if (Number.isFinite(v)) {
26635
+ if (v < lo) lo = v;
26636
+ if (v > hi) hi = v;
26637
+ }
26638
+ }
26639
+ if (lo === Infinity) return null;
26640
+ return ok({ lo, hi });
26641
+ }
25418
26642
  function binomial(n, k) {
25419
26643
  const uN = unwrapOrPropagate(n);
25420
26644
  if (!Array.isArray(uN)) return uN;
@@ -25422,13 +26646,10 @@ function binomial(n, k) {
25422
26646
  if (!Array.isArray(uK)) return uK;
25423
26647
  const [nVal] = uN;
25424
26648
  const [kVal] = uK;
25425
- const vals = [
25426
- choose(Math.round(nVal.lo), Math.round(kVal.lo)),
25427
- choose(Math.round(nVal.lo), Math.round(kVal.hi)),
25428
- choose(Math.round(nVal.hi), Math.round(kVal.lo)),
25429
- choose(Math.round(nVal.hi), Math.round(kVal.hi))
25430
- ];
25431
- return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
26649
+ const enumerated = enumerateInteger2(nVal, kVal, choose);
26650
+ if (enumerated) return enumerated;
26651
+ const nMax = Math.round(nVal.hi);
26652
+ return ok({ lo: 0, hi: choose(nMax, Math.floor(nMax / 2)) });
25432
26653
  }
25433
26654
  function gcd3(a, b) {
25434
26655
  const uA = unwrapOrPropagate(a);
@@ -25437,13 +26658,15 @@ function gcd3(a, b) {
25437
26658
  if (!Array.isArray(uB)) return uB;
25438
26659
  const [aVal] = uA;
25439
26660
  const [bVal] = uB;
25440
- const vals = [
25441
- gcd(Math.round(aVal.lo), Math.round(bVal.lo)),
25442
- gcd(Math.round(aVal.lo), Math.round(bVal.hi)),
25443
- gcd(Math.round(aVal.hi), Math.round(bVal.lo)),
25444
- gcd(Math.round(aVal.hi), Math.round(bVal.hi))
25445
- ];
25446
- return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
26661
+ const enumerated = enumerateInteger2(aVal, bVal, gcd);
26662
+ if (enumerated) return enumerated;
26663
+ const m = Math.max(
26664
+ Math.abs(Math.round(aVal.lo)),
26665
+ Math.abs(Math.round(aVal.hi)),
26666
+ Math.abs(Math.round(bVal.lo)),
26667
+ Math.abs(Math.round(bVal.hi))
26668
+ );
26669
+ return ok({ lo: 0, hi: m });
25447
26670
  }
25448
26671
  function lcm3(a, b) {
25449
26672
  const uA = unwrapOrPropagate(a);
@@ -25452,13 +26675,11 @@ function lcm3(a, b) {
25452
26675
  if (!Array.isArray(uB)) return uB;
25453
26676
  const [aVal] = uA;
25454
26677
  const [bVal] = uB;
25455
- const vals = [
25456
- lcm(Math.round(aVal.lo), Math.round(bVal.lo)),
25457
- lcm(Math.round(aVal.lo), Math.round(bVal.hi)),
25458
- lcm(Math.round(aVal.hi), Math.round(bVal.lo)),
25459
- lcm(Math.round(aVal.hi), Math.round(bVal.hi))
25460
- ];
25461
- return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
26678
+ const enumerated = enumerateInteger2(aVal, bVal, lcm);
26679
+ if (enumerated) return enumerated;
26680
+ const ma = Math.max(Math.abs(Math.round(aVal.lo)), Math.abs(Math.round(aVal.hi)));
26681
+ const mb = Math.max(Math.abs(Math.round(bVal.lo)), Math.abs(Math.round(bVal.hi)));
26682
+ return ok({ lo: 0, hi: ma * mb });
25462
26683
  }
25463
26684
  function chop2(x) {
25464
26685
  const unwrapped = unwrapOrPropagate(x);
@@ -25850,7 +27071,6 @@ var SINC_EXTREMA = [
25850
27071
  29.8116,
25851
27072
  32.95639
25852
27073
  ];
25853
- var SINC_GLOBAL_LO = -0.21724;
25854
27074
  function sinc2(x) {
25855
27075
  const unwrapped = unwrapOrPropagate(x);
25856
27076
  if (!Array.isArray(unwrapped)) return unwrapped;
@@ -25871,8 +27091,14 @@ function sinc2(x) {
25871
27091
  if (e >= xVal.lo && e <= xVal.hi) update(sincVal(e));
25872
27092
  if (-e >= xVal.lo && -e <= xVal.hi) update(sincVal(-e));
25873
27093
  }
25874
- if (Math.abs(xVal.lo) > lastExtremum || Math.abs(xVal.hi) > lastExtremum) {
25875
- update(SINC_GLOBAL_LO);
27094
+ let minBeyondAbs = Infinity;
27095
+ if (xVal.hi > lastExtremum)
27096
+ minBeyondAbs = Math.min(minBeyondAbs, Math.max(xVal.lo, lastExtremum));
27097
+ if (xVal.lo < -lastExtremum)
27098
+ minBeyondAbs = Math.min(minBeyondAbs, -Math.min(xVal.hi, -lastExtremum));
27099
+ if (Number.isFinite(minBeyondAbs) && minBeyondAbs > 0) {
27100
+ update(1 / minBeyondAbs);
27101
+ update(-1 / minBeyondAbs);
25876
27102
  }
25877
27103
  return ok({ lo, hi });
25878
27104
  }
@@ -25898,8 +27124,21 @@ function fresnelS2(x) {
25898
27124
  if (e >= xVal.lo && e <= xVal.hi) update(fresnelS(e));
25899
27125
  if (-e >= xVal.lo && -e <= xVal.hi) update(fresnelS(-e));
25900
27126
  }
27127
+ fresnelConvergenceBound(xVal, FRESNEL_S_EXTREMA, fresnelS, update);
25901
27128
  return ok({ lo, hi });
25902
27129
  }
27130
+ function fresnelConvergenceBound(xVal, extrema, scalar, update) {
27131
+ const lastE = extrema[extrema.length - 1];
27132
+ const amp = Math.abs(scalar(lastE) - 0.5);
27133
+ if (xVal.hi > lastE) {
27134
+ update(0.5 + amp);
27135
+ update(0.5 - amp);
27136
+ }
27137
+ if (xVal.lo < -lastE) {
27138
+ update(-0.5 - amp);
27139
+ update(-0.5 + amp);
27140
+ }
27141
+ }
25903
27142
  function fresnelC2(x) {
25904
27143
  const unwrapped = unwrapOrPropagate(x);
25905
27144
  if (!Array.isArray(unwrapped)) return unwrapped;
@@ -25916,6 +27155,7 @@ function fresnelC2(x) {
25916
27155
  if (e >= xVal.lo && e <= xVal.hi) update(fresnelC(e));
25917
27156
  if (-e >= xVal.lo && -e <= xVal.hi) update(fresnelC(-e));
25918
27157
  }
27158
+ fresnelConvergenceBound(xVal, FRESNEL_C_EXTREMA, fresnelC, update);
25919
27159
  return ok({ lo, hi });
25920
27160
  }
25921
27161
 
@@ -26023,11 +27263,9 @@ function clamp(x, lo, hi) {
26023
27263
  const unwrapped = unwrapOrPropagate(x, lo, hi);
26024
27264
  if (!Array.isArray(unwrapped)) return unwrapped;
26025
27265
  const [xVal, loVal, hiVal] = unwrapped;
26026
- const resultLo = Math.max(xVal.lo, loVal.lo);
26027
- const resultHi = Math.min(xVal.hi, hiVal.hi);
26028
- if (resultLo > resultHi) {
26029
- return { kind: "empty" };
26030
- }
27266
+ const lowered = { lo: Math.max(xVal.lo, loVal.lo), hi: Math.max(xVal.hi, loVal.hi) };
27267
+ const resultLo = Math.min(lowered.lo, hiVal.lo);
27268
+ const resultHi = Math.min(lowered.hi, hiVal.hi);
26031
27269
  return { kind: "interval", value: { lo: resultLo, hi: resultHi } };
26032
27270
  }
26033
27271
 
@@ -26360,7 +27598,7 @@ function extractIntervalLimits(limitsExpr) {
26360
27598
  function compileIntervalBound(expr, numVal, target) {
26361
27599
  if (numVal !== void 0) return String(numVal);
26362
27600
  const compiled = BaseCompiler.compile(expr, target);
26363
- return `Math.floor((${compiled}).hi)`;
27601
+ return `Math.floor(((_b) => (_b && _b.value ? _b.value.hi : _b.hi))(${compiled}))`;
26364
27602
  }
26365
27603
  function compileIntervalSumProduct(kind, args, _compile, target) {
26366
27604
  if (!args[0]) throw new Error(`${kind}: no body`);
@@ -26546,7 +27784,7 @@ function compileToIntervalTarget(expr, target) {
26546
27784
  }
26547
27785
 
26548
27786
  // src/compile.ts
26549
- var version = "0.58.0";
27787
+ var version = "0.59.0";
26550
27788
  export {
26551
27789
  BaseCompiler,
26552
27790
  GLSLTarget,