@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
- /** Compile 0.58.0 */
1
+ /** Compile 0.59.0 */
2
2
  (function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Compile = {}));})(this, (function (exports) { 'use strict';
3
3
  var Compile = (() => {
4
4
  var __defProp = Object.defineProperty;
@@ -192,6 +192,7 @@ var Compile = (() => {
192
192
  return sum;
193
193
  }
194
194
  function fpln(x, scale) {
195
+ if (x <= 0n) throw new RangeError("fpln: input must be positive");
195
196
  if (x === scale) return 0n;
196
197
  const xNum = Number(x);
197
198
  const scaleNum = Number(scale);
@@ -841,9 +842,11 @@ var Compile = (() => {
841
842
  if (Number.isFinite(thisExp) && Number.isFinite(otherExp)) {
842
843
  if (other.significand === 0n) return _BigDecimal.NAN;
843
844
  if (this.significand === 0n) return fromRaw(0n, 0);
844
- return this.sub(this.div(other).trunc().mul(other)).toPrecision(
845
- _BigDecimal.precision
846
- );
845
+ const ediff = thisExp - otherExp;
846
+ const num = ediff >= 0 ? this.significand * pow10(ediff) : this.significand;
847
+ const den = ediff >= 0 ? other.significand : other.significand * pow10(-ediff);
848
+ const q = num / den;
849
+ return this.sub(fromRaw(q, 0).mul(other));
847
850
  }
848
851
  if (thisExp !== thisExp || otherExp !== otherExp) return _BigDecimal.NAN;
849
852
  if (!Number.isFinite(thisExp)) return _BigDecimal.NAN;
@@ -888,7 +891,10 @@ var Compile = (() => {
888
891
  return this.pow(n.neg()).inv();
889
892
  }
890
893
  const absSig = this.significand < 0n ? -this.significand : this.significand;
891
- const thisLog10 = bigintDigits(absSig) + this.exponent;
894
+ const sigDigits = bigintDigits(absSig);
895
+ const dropped = sigDigits > 15 ? sigDigits - 15 : 0;
896
+ const lead = dropped > 0 ? Number(absSig / 10n ** BigInt(dropped)) : Number(absSig);
897
+ const thisLog10 = Math.log10(lead) + dropped + this.exponent;
892
898
  const resultLog10 = Number(expValue) * thisLog10;
893
899
  if (resultLog10 > 9e15) {
894
900
  return this.significand < 0n && expValue % 2n !== 0n ? _BigDecimal.NEGATIVE_INFINITY : _BigDecimal.POSITIVE_INFINITY;
@@ -921,7 +927,19 @@ var Compile = (() => {
921
927
  return _BigDecimal.POSITIVE_INFINITY;
922
928
  }
923
929
  if (this.significand < 0n) return _BigDecimal.NAN;
924
- return n.mul(this.ln()).exp();
930
+ const baseSig = this.significand;
931
+ const decExpBase = this.exponent + bigintDigits(baseSig) - 1;
932
+ const nSig = n.significand < 0n ? -n.significand : n.significand;
933
+ const decExpN = n.exponent + bigintDigits(nSig) - 1;
934
+ const argMag = decExpN + Math.log10(Math.abs(decExpBase) * 2.303 + 3) + 1;
935
+ const extra = Math.min(20, Math.max(2, Math.ceil(argMag) + 2));
936
+ const savedPrec = _BigDecimal.precision;
937
+ _BigDecimal.precision = savedPrec + extra;
938
+ try {
939
+ return n.mul(this.ln()).exp().toPrecision(savedPrec);
940
+ } finally {
941
+ _BigDecimal.precision = savedPrec;
942
+ }
925
943
  }
926
944
  // ---------- Conversion methods ----------
927
945
  /** Convert to a JavaScript number. May lose precision for large values. */
@@ -1162,6 +1180,20 @@ var Compile = (() => {
1162
1180
  const sig = negative ? -absFp : absFp;
1163
1181
  return fromRaw(sig, resultExp);
1164
1182
  }
1183
+ function decimalExponent(x) {
1184
+ const sig = x.significand < 0n ? -x.significand : x.significand;
1185
+ return x.exponent + bigintDigits(sig) - 1;
1186
+ }
1187
+ var MAX_SAFE_EXPONENT = BigInt(Number.MAX_SAFE_INTEGER);
1188
+ var _ln10Fp = null;
1189
+ var _ln10Scale = null;
1190
+ function ln10Fixed(scale) {
1191
+ if (_ln10Scale !== scale) {
1192
+ _ln10Fp = fpln(10n * scale, scale);
1193
+ _ln10Scale = scale;
1194
+ }
1195
+ return _ln10Fp;
1196
+ }
1165
1197
  BigDecimal.prototype.sqrt = function() {
1166
1198
  if (this.isNaN()) return BigDecimal.NAN;
1167
1199
  if (this.isZero()) return BigDecimal.ZERO;
@@ -1172,9 +1204,13 @@ var Compile = (() => {
1172
1204
  if (this.significand < 0n) return BigDecimal.NAN;
1173
1205
  const targetPrec = BigDecimal.precision;
1174
1206
  const workingPrec = targetPrec + 10;
1175
- const [fp, scale] = toFixedPoint(this, workingPrec);
1207
+ const e = decimalExponent(this);
1208
+ const k = Math.floor(e / 2);
1209
+ const m = fromRaw(this.significand, this.exponent - 2 * k);
1210
+ const [fp, scale] = toFixedPoint(m, workingPrec);
1176
1211
  const sqrtFp = fpsqrt(fp, scale);
1177
- return fromFixedPoint(sqrtFp, scale, targetPrec);
1212
+ const root = fromFixedPoint(sqrtFp, scale, targetPrec);
1213
+ return fromRaw(root.significand, root.exponent + k);
1178
1214
  };
1179
1215
  BigDecimal.prototype.cbrt = function() {
1180
1216
  if (this.isNaN()) return BigDecimal.NAN;
@@ -1188,10 +1224,13 @@ var Compile = (() => {
1188
1224
  }
1189
1225
  const targetPrec = BigDecimal.precision;
1190
1226
  const workingPrec = targetPrec + 10;
1191
- const [fp, scale] = toFixedPoint(this, workingPrec);
1227
+ const e = decimalExponent(this);
1228
+ const k = Math.floor(e / 3);
1229
+ const m = fromRaw(this.significand, this.exponent - 3 * k);
1230
+ const [fp, scale] = toFixedPoint(m, workingPrec);
1192
1231
  const C = fp * scale * scale;
1193
1232
  let x;
1194
- const numVal = this.toNumber();
1233
+ const numVal = m.toNumber();
1195
1234
  const scaleNum = Number(scale);
1196
1235
  if (Number.isFinite(numVal) && numVal > 0 && Number.isFinite(scaleNum)) {
1197
1236
  const approx = Math.cbrt(numVal);
@@ -1220,7 +1259,8 @@ var Compile = (() => {
1220
1259
  const diffNext = bigintAbs(next * next * next - C);
1221
1260
  if (diffNext < diffX) x = next;
1222
1261
  }
1223
- return fromFixedPoint(x, scale, targetPrec);
1262
+ const root = fromFixedPoint(x, scale, targetPrec);
1263
+ return fromRaw(root.significand, root.exponent + k);
1224
1264
  };
1225
1265
  BigDecimal.sqrt = function(x) {
1226
1266
  return x.sqrt();
@@ -1235,11 +1275,27 @@ var Compile = (() => {
1235
1275
  return BigDecimal.ZERO;
1236
1276
  }
1237
1277
  if (this.isZero()) return BigDecimal.ONE;
1278
+ if (decimalExponent(this) >= 17)
1279
+ return this.significand > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
1238
1280
  const targetPrec = BigDecimal.precision;
1239
- const workingPrec = targetPrec + 15;
1240
- const [fp, scale] = toFixedPoint(this, workingPrec);
1241
- const expFp = fpexp(fp, scale);
1242
- return fromFixedPoint(expFp, scale, targetPrec);
1281
+ const absSig = this.significand < 0n ? -this.significand : this.significand;
1282
+ const magnitude = Math.max(0, this.exponent + bigintDigits(absSig));
1283
+ const workingPrec = targetPrec + 20 + magnitude;
1284
+ const [xFp, scale] = toFixedPoint(this, workingPrec);
1285
+ const l10 = ln10Fixed(scale);
1286
+ let k = xFp / l10;
1287
+ let rFp = xFp - k * l10;
1288
+ if (rFp < 0n) {
1289
+ k -= 1n;
1290
+ rFp += l10;
1291
+ }
1292
+ if (k > MAX_SAFE_EXPONENT || k < -MAX_SAFE_EXPONENT)
1293
+ return k > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
1294
+ const expR = fromFixedPoint(fpexp(rFp, scale), scale, targetPrec);
1295
+ const newExp = expR.exponent + Number(k);
1296
+ if (!Number.isSafeInteger(newExp))
1297
+ return k > 0n ? BigDecimal.POSITIVE_INFINITY : BigDecimal.ZERO;
1298
+ return fromRaw(expR.significand, newExp);
1243
1299
  };
1244
1300
  BigDecimal.prototype.ln = function() {
1245
1301
  if (this.isNaN()) return BigDecimal.NAN;
@@ -1251,10 +1307,16 @@ var Compile = (() => {
1251
1307
  if (this.significand < 0n) return BigDecimal.NAN;
1252
1308
  if (this.eq(1)) return BigDecimal.ZERO;
1253
1309
  const targetPrec = BigDecimal.precision;
1254
- const workingPrec = targetPrec + 15;
1255
- const [fp, scale] = toFixedPoint(this, workingPrec);
1256
- const lnFp = fpln(fp, scale);
1257
- return fromFixedPoint(lnFp, scale, targetPrec);
1310
+ const sig = this.significand;
1311
+ const digits = bigintDigits(sig);
1312
+ const e = this.exponent + digits - 1;
1313
+ const m = fromRaw(sig, -(digits - 1));
1314
+ const eDigits = Math.abs(e).toString().length;
1315
+ const workingPrec = targetPrec + 20 + eDigits;
1316
+ const [mFp, scale] = toFixedPoint(m, workingPrec);
1317
+ const l10 = ln10Fixed(scale);
1318
+ const resultFp = fpln(mFp, scale) + BigInt(e) * l10;
1319
+ return fromFixedPoint(resultFp, scale, targetPrec);
1258
1320
  };
1259
1321
  BigDecimal.prototype.log = function(base) {
1260
1322
  const b = base instanceof BigDecimal ? base : new BigDecimal(base);
@@ -1274,7 +1336,10 @@ var Compile = (() => {
1274
1336
  if (!this.isFinite()) return BigDecimal.NAN;
1275
1337
  if (this.isZero()) return BigDecimal.ZERO;
1276
1338
  const targetPrec = BigDecimal.precision;
1277
- const workingPrec = targetPrec + 15;
1339
+ const e = decimalExponent(this);
1340
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1341
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
1342
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
1278
1343
  const [fp, scale] = toFixedPoint(this, workingPrec);
1279
1344
  const [sinFp] = fpsincos(fp, scale);
1280
1345
  return fromFixedPoint(sinFp, scale, targetPrec);
@@ -1285,6 +1350,8 @@ var Compile = (() => {
1285
1350
  if (this.isZero()) return BigDecimal.ONE;
1286
1351
  const targetPrec = BigDecimal.precision;
1287
1352
  const workingPrec = targetPrec + 15;
1353
+ const e = decimalExponent(this);
1354
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
1288
1355
  const [fp, scale] = toFixedPoint(this, workingPrec);
1289
1356
  const [, cosFp] = fpsincos(fp, scale);
1290
1357
  return fromFixedPoint(cosFp, scale, targetPrec);
@@ -1294,7 +1361,10 @@ var Compile = (() => {
1294
1361
  if (!this.isFinite()) return BigDecimal.NAN;
1295
1362
  if (this.isZero()) return BigDecimal.ZERO;
1296
1363
  const targetPrec = BigDecimal.precision;
1297
- const workingPrec = targetPrec + 15;
1364
+ const e = decimalExponent(this);
1365
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1366
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
1367
+ if (e > PI_DIGITS.length - workingPrec - 30) return BigDecimal.NAN;
1298
1368
  const [fp, scale] = toFixedPoint(this, workingPrec);
1299
1369
  const [sinFp, cosFp] = fpsincos(fp, scale);
1300
1370
  if (cosFp === 0n) {
@@ -1312,7 +1382,9 @@ var Compile = (() => {
1312
1382
  return piHalf.neg();
1313
1383
  }
1314
1384
  const targetPrec = BigDecimal.precision;
1315
- const workingPrec = targetPrec + 15;
1385
+ const e = decimalExponent(this);
1386
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1387
+ const workingPrec = targetPrec + 15 + (e < 0 ? -e : 0);
1316
1388
  const [fp, scale] = toFixedPoint(this, workingPrec);
1317
1389
  const atanFp = fpatan(fp, scale);
1318
1390
  return fromFixedPoint(atanFp, scale, targetPrec);
@@ -1329,7 +1401,9 @@ var Compile = (() => {
1329
1401
  return this.significand > 0n ? piHalf : piHalf.neg();
1330
1402
  }
1331
1403
  const targetPrec = BigDecimal.precision;
1332
- const workingPrec = targetPrec + 20;
1404
+ const e = decimalExponent(this);
1405
+ if (e < 0 && -2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1406
+ const workingPrec = targetPrec + 20 + (e < 0 ? -e : 0);
1333
1407
  const [xFp, scale] = toFixedPoint(this, workingPrec);
1334
1408
  const x2 = fpmul(xFp, xFp, scale);
1335
1409
  const oneMinusX2 = scale - x2;
@@ -1392,6 +1466,23 @@ var Compile = (() => {
1392
1466
  if (this.significand > 0n) return BigDecimal.POSITIVE_INFINITY;
1393
1467
  return BigDecimal.NEGATIVE_INFINITY;
1394
1468
  }
1469
+ const targetPrec = BigDecimal.precision;
1470
+ const e = decimalExponent(this);
1471
+ if (e < 0) {
1472
+ if (-2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1473
+ const saved = BigDecimal.precision;
1474
+ BigDecimal.precision = targetPrec - e + 5;
1475
+ try {
1476
+ const expX2 = this.exp();
1477
+ return expX2.sub(expX2.inv()).div(BigDecimal.TWO).toPrecision(targetPrec);
1478
+ } finally {
1479
+ BigDecimal.precision = saved;
1480
+ }
1481
+ }
1482
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3)) {
1483
+ const h = this.abs().exp().div(BigDecimal.TWO);
1484
+ return this.significand > 0n ? h : h.neg();
1485
+ }
1395
1486
  const expX = this.exp();
1396
1487
  const expNegX = expX.inv();
1397
1488
  return expX.sub(expNegX).div(BigDecimal.TWO);
@@ -1402,6 +1493,9 @@ var Compile = (() => {
1402
1493
  if (!this.isFinite()) {
1403
1494
  return BigDecimal.POSITIVE_INFINITY;
1404
1495
  }
1496
+ const targetPrec = BigDecimal.precision;
1497
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3))
1498
+ return this.abs().exp().div(BigDecimal.TWO);
1405
1499
  const expX = this.exp();
1406
1500
  const expNegX = expX.inv();
1407
1501
  return expX.add(expNegX).div(BigDecimal.TWO);
@@ -1413,6 +1507,21 @@ var Compile = (() => {
1413
1507
  if (this.significand > 0n) return BigDecimal.ONE;
1414
1508
  return BigDecimal.NEGATIVE_ONE;
1415
1509
  }
1510
+ const targetPrec = BigDecimal.precision;
1511
+ const e = decimalExponent(this);
1512
+ if (e < 0) {
1513
+ if (-2 * e >= targetPrec + 4) return this.toPrecision(targetPrec);
1514
+ const saved = BigDecimal.precision;
1515
+ BigDecimal.precision = targetPrec - e + 5;
1516
+ try {
1517
+ const exp2x2 = this.mul(BigDecimal.TWO).exp();
1518
+ return exp2x2.sub(BigDecimal.ONE).div(exp2x2.add(BigDecimal.ONE)).toPrecision(targetPrec);
1519
+ } finally {
1520
+ BigDecimal.precision = saved;
1521
+ }
1522
+ }
1523
+ if (Math.abs(this.toNumber()) > 1.16 * (targetPrec + 3))
1524
+ return this.significand > 0n ? BigDecimal.ONE : BigDecimal.NEGATIVE_ONE;
1416
1525
  const exp2x = this.mul(BigDecimal.TWO).exp();
1417
1526
  return exp2x.sub(BigDecimal.ONE).div(exp2x.add(BigDecimal.ONE));
1418
1527
  };
@@ -1461,6 +1570,7 @@ var Compile = (() => {
1461
1570
  Math.log10(Math.pow(2, MACHINE_PRECISION_BITS))
1462
1571
  );
1463
1572
  var DEFAULT_TOLERANCE = 1e-10;
1573
+ var SMALL_INTEGER = 1e6;
1464
1574
  var MAX_ITERATION = 1e4;
1465
1575
  function gcd(a, b) {
1466
1576
  if (a === 0) return b;
@@ -1472,7 +1582,8 @@ var Compile = (() => {
1472
1582
  }
1473
1583
  function lcm(a, b) {
1474
1584
  if (a === 0 || b === 0) return 0;
1475
- const res = BigInt(a) * BigInt(b) / BigInt(gcd(a, b));
1585
+ let res = BigInt(a) * BigInt(b) / BigInt(gcd(a, b));
1586
+ if (res < 0n) res = -res;
1476
1587
  return Number(res);
1477
1588
  }
1478
1589
  function factorial(n) {
@@ -1562,216 +1673,27 @@ var Compile = (() => {
1562
1673
  "error",
1563
1674
  ...EXPRESSION_TYPES
1564
1675
  ];
1676
+ var NUMERIC_TYPES_SET = new Set(
1677
+ NUMERIC_TYPES
1678
+ );
1679
+ var COLLECTION_TYPES_SET = new Set(
1680
+ COLLECTION_TYPES
1681
+ );
1682
+ var SCALAR_TYPES_SET = new Set(
1683
+ SCALAR_TYPES
1684
+ );
1685
+ var PRIMITIVE_TYPES_SET = new Set(
1686
+ PRIMITIVE_TYPES
1687
+ );
1688
+ function isValidPrimitiveType(s) {
1689
+ if (typeof s !== "string") return false;
1690
+ return PRIMITIVE_TYPES_SET.has(s);
1691
+ }
1565
1692
  function isValidType(t) {
1566
- if (typeof t === "string")
1567
- return PRIMITIVE_TYPES.includes(t);
1693
+ if (typeof t === "string") return PRIMITIVE_TYPES_SET.has(t);
1568
1694
  if (typeof t !== "object") return false;
1569
1695
  if (!("kind" in t)) return false;
1570
- 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";
1571
- }
1572
-
1573
- // src/common/type/serialize.ts
1574
- var NEGATION_PRECEDENCE = 3;
1575
- var UNION_PRECEDENCE = 1;
1576
- var INTERSECTION_PRECEDENCE = 2;
1577
- var LIST_PRECEDENCE = 4;
1578
- var RECORD_PRECEDENCE = 5;
1579
- var DICTIONARY_PRECEDENCE = 6;
1580
- var SET_PRECEDENCE = 7;
1581
- var COLLECTION_PRECEDENCE = 8;
1582
- var TUPLE_PRECEDENCE = 9;
1583
- var SIGNATURE_PRECEDENCE = 10;
1584
- var VALUE_PRECEDENCE = 11;
1585
- function typeToString(type, precedence = 0) {
1586
- if (typeof type === "string") return type;
1587
- let result = "";
1588
- switch (type.kind) {
1589
- case "value":
1590
- if (typeof type.value === "string") result = `"${type.value}"`;
1591
- else if (typeof type.value === "boolean")
1592
- result = type.value ? "true" : "false";
1593
- else result = type.value.toString();
1594
- break;
1595
- case "reference":
1596
- result = type.name;
1597
- break;
1598
- case "negation":
1599
- result = `!${typeToString(type.type, NEGATION_PRECEDENCE)}`;
1600
- break;
1601
- case "union":
1602
- result = type.types.map((t) => typeToString(t, UNION_PRECEDENCE)).join(" | ");
1603
- break;
1604
- case "intersection":
1605
- result = type.types.map((t) => typeToString(t, INTERSECTION_PRECEDENCE)).join(" & ");
1606
- break;
1607
- case "expression":
1608
- result = `expression<${symbolName(type.operator)}>`;
1609
- break;
1610
- case "symbol":
1611
- result = `symbol<${symbolName(type.name)}>`;
1612
- break;
1613
- case "numeric":
1614
- if (Number.isFinite(type.lower) && Number.isFinite(type.upper)) {
1615
- result = `${type.type}<${type.lower}..${type.upper}>`;
1616
- } else if (Number.isFinite(type.lower)) {
1617
- result = `${type.type}<${type.lower}..>`;
1618
- } else if (Number.isFinite(type.upper)) {
1619
- result = `${type.type}<..${type.upper}>`;
1620
- } else {
1621
- result = `${type.type}`;
1622
- }
1623
- break;
1624
- case "list":
1625
- if (type.dimensions && typeof type.elements === "string" && NUMERIC_TYPES.includes(type.elements)) {
1626
- if (type.dimensions === void 0) {
1627
- if (type.elements === "number") result = "tensor";
1628
- } else if (type.dimensions.length === 1) {
1629
- if (type.elements === "number") {
1630
- if (type.dimensions[0] < 0) result = "vector";
1631
- else result = `vector<${type.dimensions[0]}>`;
1632
- } else {
1633
- if (type.dimensions[0] < 0)
1634
- result = `vector<${typeToString(type.elements)}>`;
1635
- else
1636
- result = `vector<${typeToString(type.elements)}^${type.dimensions[0]}>`;
1637
- }
1638
- } else if (type.dimensions.length === 2) {
1639
- const dims = type.dimensions;
1640
- if (type.elements === "number") {
1641
- if (dims[0] < 0 && dims[1] < 0) result = "matrix";
1642
- else result = `matrix<${dims[0]}x${dims[1]}>`;
1643
- } else {
1644
- if (dims[0] < 0 && dims[1] < 0)
1645
- result = `matrix<${typeToString(type.elements)}>`;
1646
- else
1647
- result = `matrix<${typeToString(type.elements)}^(${dims[0]}x${dims[1]})>`;
1648
- }
1649
- }
1650
- }
1651
- if (!result) {
1652
- const dimensions = type.dimensions ? type.dimensions.length === 1 ? `^${type.dimensions[0].toString()}` : `^(${type.dimensions.join("x")})` : "";
1653
- result = `list<${typeToString(type.elements)}${dimensions}>`;
1654
- }
1655
- break;
1656
- case "record":
1657
- const elements = Object.entries(type.elements).map(([key, value]) => `${key}: ${typeToString(value)}`).join(", ");
1658
- result = `record<${elements}>`;
1659
- break;
1660
- case "dictionary":
1661
- result = `dictionary<${typeToString(type.values)}>`;
1662
- break;
1663
- case "set":
1664
- result = `set<${typeToString(type.elements)}>`;
1665
- break;
1666
- case "collection":
1667
- result = `collection<${typeToString(type.elements)}>`;
1668
- break;
1669
- case "indexed_collection":
1670
- result = `indexed_collection<${typeToString(type.elements)}>`;
1671
- break;
1672
- case "tuple":
1673
- if (type.elements.length === 0) result = "tuple";
1674
- else if (type.elements.length === 1) {
1675
- const [el] = type.elements;
1676
- result = `tuple<${namedElement(el)}>`;
1677
- } else {
1678
- result = "tuple<" + type.elements.map((el) => namedElement(el)).join(", ") + ">";
1679
- }
1680
- break;
1681
- case "signature":
1682
- const args = type.args ? type.args.map((arg) => namedElement(arg)).join(", ") : "";
1683
- const optArgs = type.optArgs ? type.optArgs.map((arg) => namedElement(arg) + "?").join(", ") : "";
1684
- const varArg = type.variadicArg ? type.variadicMin === 0 ? `${namedElement(type.variadicArg)}*` : `${namedElement(type.variadicArg)}+` : "";
1685
- const argsList = [args, optArgs, varArg].filter((s) => s).join(", ");
1686
- result = `(${argsList}) -> ${typeToString(type.result)}`;
1687
- break;
1688
- default:
1689
- result = "error";
1690
- }
1691
- if (precedence > 0 && precedence > getPrecedence(type.kind))
1692
- return `(${result})`;
1693
- return result;
1694
- }
1695
- function namedElement(el) {
1696
- if (el.name) return `${el.name}: ${typeToString(el.type)}`;
1697
- return typeToString(el.type);
1698
- }
1699
- function symbolName(name) {
1700
- if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) return name;
1701
- return `\`${name}\``;
1702
- }
1703
- function getPrecedence(kind) {
1704
- switch (kind) {
1705
- case "negation":
1706
- return NEGATION_PRECEDENCE;
1707
- case "union":
1708
- return UNION_PRECEDENCE;
1709
- case "intersection":
1710
- return INTERSECTION_PRECEDENCE;
1711
- case "list":
1712
- return LIST_PRECEDENCE;
1713
- case "record":
1714
- return RECORD_PRECEDENCE;
1715
- case "dictionary":
1716
- return DICTIONARY_PRECEDENCE;
1717
- case "set":
1718
- return SET_PRECEDENCE;
1719
- case "collection":
1720
- case "indexed_collection":
1721
- return COLLECTION_PRECEDENCE;
1722
- case "tuple":
1723
- return TUPLE_PRECEDENCE;
1724
- case "signature":
1725
- return SIGNATURE_PRECEDENCE;
1726
- case "value":
1727
- return VALUE_PRECEDENCE;
1728
- default:
1729
- return 0;
1730
- }
1731
- }
1732
-
1733
- // src/common/fuzzy-string-match.ts
1734
- function levenshtein(source, target) {
1735
- if (source === target) return 0;
1736
- if (source.length === 0) return target.length;
1737
- if (target.length === 0) return source.length;
1738
- let prevRow = Array.from(
1739
- { length: source.length + 1 },
1740
- (_, j) => j
1741
- );
1742
- let currRow = new Array(source.length + 1);
1743
- for (let i = 1; i <= target.length; i++) {
1744
- currRow[0] = i;
1745
- for (let j = 1; j <= source.length; j++) {
1746
- const cost = source[j - 1] === target[i - 1] ? 0 : 1;
1747
- currRow[j] = Math.min(
1748
- prevRow[j] + 1,
1749
- // deletion
1750
- currRow[j - 1] + 1,
1751
- // insertion
1752
- prevRow[j - 1] + cost
1753
- // substitution
1754
- );
1755
- }
1756
- [prevRow, currRow] = [currRow, prevRow];
1757
- }
1758
- return prevRow[source.length];
1759
- }
1760
- function fuzzyStringMatch(invalidWord, validWords) {
1761
- const threshold = 7;
1762
- let bestMatch = null;
1763
- let minDistance = Infinity;
1764
- const invalidLength = invalidWord.length;
1765
- for (const word of validWords) {
1766
- if (Math.abs(invalidLength - word.length) > threshold) continue;
1767
- const distance = levenshtein(invalidWord, word);
1768
- if (distance === 0) return word;
1769
- if (distance <= threshold && distance < minDistance) {
1770
- minDistance = distance;
1771
- bestMatch = word;
1772
- }
1773
- }
1774
- return bestMatch;
1696
+ 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";
1775
1697
  }
1776
1698
 
1777
1699
  // src/common/type/lexer.ts
@@ -2481,19 +2403,13 @@ var Compile = (() => {
2481
2403
  );
2482
2404
  let dimensions;
2483
2405
  if (this.match("<")) {
2484
- dimensions = this.parseDimensionWithX();
2485
- if (!dimensions) {
2486
- dimensions = this.parseDimensions();
2487
- }
2406
+ dimensions = this.parseDimensions();
2488
2407
  if (!dimensions) {
2489
2408
  const type = this.parseUnionType();
2490
2409
  if (type) {
2491
2410
  elementType = type;
2492
2411
  if (this.match("^")) {
2493
- dimensions = this.parseDimensionWithX();
2494
- if (!dimensions) {
2495
- dimensions = this.parseDimensions();
2496
- }
2412
+ dimensions = this.parseCaretDimensions();
2497
2413
  }
2498
2414
  }
2499
2415
  }
@@ -2534,19 +2450,13 @@ var Compile = (() => {
2534
2450
  );
2535
2451
  let dimensions;
2536
2452
  if (this.match("<")) {
2537
- dimensions = this.parseDimensionWithX();
2538
- if (!dimensions) {
2539
- dimensions = this.parseDimensions();
2540
- }
2453
+ dimensions = this.parseDimensions();
2541
2454
  if (!dimensions) {
2542
2455
  const type = this.parseUnionType();
2543
2456
  if (type) {
2544
2457
  elementType = type;
2545
2458
  if (this.match("^")) {
2546
- dimensions = this.parseDimensionWithX();
2547
- if (!dimensions) {
2548
- dimensions = this.parseDimensions();
2549
- }
2459
+ dimensions = this.parseCaretDimensions();
2550
2460
  }
2551
2461
  }
2552
2462
  }
@@ -2577,16 +2487,30 @@ var Compile = (() => {
2577
2487
  return this.createNode("tensor", { elementType });
2578
2488
  }
2579
2489
  parseDimensions() {
2580
- const dimensions = [];
2581
2490
  const firstDim = this.parseDimension();
2582
2491
  if (!firstDim) return void 0;
2583
- dimensions.push(firstDim);
2584
- while (this.match("x")) {
2585
- const dim = this.parseDimension();
2586
- if (!dim) {
2587
- this.error("Expected dimension after x");
2492
+ const dimensions = [firstDim];
2493
+ for (; ; ) {
2494
+ const tok = this.current;
2495
+ if (tok.type === "IDENTIFIER" && /^(x\d+)+$/.test(tok.value)) {
2496
+ this.advance();
2497
+ for (const m of tok.value.match(/x(\d+)/g))
2498
+ dimensions.push(
2499
+ this.createNode("dimension", {
2500
+ size: parseInt(m.slice(1))
2501
+ })
2502
+ );
2503
+ } else if (tok.type === "IDENTIFIER" && tok.value === "x") {
2504
+ const next = this.lexer.peekToken();
2505
+ if (next.type !== "NUMBER_LITERAL" && next.type !== "?")
2506
+ this.error(
2507
+ "Expected a positive integer literal or `?` after x. For example: `2x3` or `2x?`"
2508
+ );
2509
+ this.advance();
2510
+ dimensions.push(this.parseDimension());
2511
+ } else {
2512
+ break;
2588
2513
  }
2589
- dimensions.push(dim);
2590
2514
  }
2591
2515
  return dimensions;
2592
2516
  }
@@ -2600,35 +2524,11 @@ var Compile = (() => {
2600
2524
  }
2601
2525
  return void 0;
2602
2526
  }
2603
- parseDimensionWithX() {
2604
- if (this.current.type === "NUMBER_LITERAL") {
2605
- const dimensions = [];
2606
- const firstDim = parseInt(this.advance().value);
2607
- dimensions.push(
2608
- this.createNode("dimension", { size: firstDim })
2609
- );
2610
- if (this.current.type === "IDENTIFIER" && this.current.value.startsWith("x")) {
2611
- const dimString = this.current.value;
2612
- const matches = dimString.match(/x(\d+)/g);
2613
- if (matches && matches.join("") === dimString) {
2614
- this.advance();
2615
- for (const match of matches) {
2616
- const dimValue = parseInt(match.substring(1));
2617
- dimensions.push(
2618
- this.createNode("dimension", { size: dimValue })
2619
- );
2620
- }
2621
- } else if (dimString === "x" || dimString.startsWith("x")) {
2622
- this.error(
2623
- "Expected a positive integer literal or `?` after x. For example: `2x3` or `2x?`"
2624
- );
2625
- }
2626
- }
2627
- if (dimensions.length > 1) {
2628
- return dimensions;
2629
- }
2630
- }
2631
- return void 0;
2527
+ parseCaretDimensions() {
2528
+ const paren = this.match("(");
2529
+ const dimensions = this.parseDimensions();
2530
+ if (paren) this.expect(")");
2531
+ return dimensions;
2632
2532
  }
2633
2533
  parseTupleType() {
2634
2534
  if (this.current.type === "IDENTIFIER" && this.current.value === "tuple") {
@@ -2813,6 +2713,18 @@ var Compile = (() => {
2813
2713
  this.expect("..");
2814
2714
  const upperBound = this.parseValue();
2815
2715
  this.expect(">");
2716
+ const lower = lowerBound?.value ?? -Infinity;
2717
+ const upper = upperBound?.value ?? Infinity;
2718
+ if (Number.isNaN(lower) || Number.isNaN(upper))
2719
+ this.error(
2720
+ "Invalid numeric type",
2721
+ "Lower and upper bounds must be valid numbers"
2722
+ );
2723
+ if (lower > upper)
2724
+ this.error(
2725
+ `Invalid range: ${lower}..${upper}`,
2726
+ "The lower bound must be less than the upper bound"
2727
+ );
2816
2728
  return this.createNode("numeric", {
2817
2729
  baseType,
2818
2730
  lowerBound,
@@ -2827,7 +2739,7 @@ var Compile = (() => {
2827
2739
  parsePrimitiveType() {
2828
2740
  if (this.current.type === "IDENTIFIER") {
2829
2741
  const name = this.current.value;
2830
- if (PRIMITIVE_TYPES.includes(name)) {
2742
+ if (PRIMITIVE_TYPES_SET.has(name)) {
2831
2743
  this.advance();
2832
2744
  return this.createNode("primitive", { name });
2833
2745
  }
@@ -3161,14 +3073,32 @@ var Compile = (() => {
3161
3073
  }
3162
3074
 
3163
3075
  // src/common/type/parse.ts
3076
+ var TYPE_CACHE = /* @__PURE__ */ new Map();
3077
+ var TYPE_CACHE_MAX_SIZE = 2048;
3078
+ function deepFreeze(obj) {
3079
+ if (obj === null || typeof obj !== "object") return obj;
3080
+ if (Object.isFrozen(obj)) return obj;
3081
+ Object.freeze(obj);
3082
+ for (const value of Object.values(obj)) deepFreeze(value);
3083
+ return obj;
3084
+ }
3164
3085
  function parseType(s, typeResolver) {
3165
3086
  if (s === void 0) return void 0;
3166
3087
  if (isValidType(s)) return s;
3167
3088
  if (typeof s !== "string") return void 0;
3089
+ const cacheable = typeResolver === void 0;
3090
+ if (cacheable) {
3091
+ const cached = TYPE_CACHE.get(s);
3092
+ if (cached !== void 0) return cached;
3093
+ }
3168
3094
  try {
3169
3095
  const parser = new Parser(s, { typeResolver });
3170
3096
  const ast = parser.parseType();
3171
3097
  const type = buildTypeFromAST(ast, typeResolver);
3098
+ if (cacheable) {
3099
+ if (TYPE_CACHE.size >= TYPE_CACHE_MAX_SIZE) TYPE_CACHE.clear();
3100
+ TYPE_CACHE.set(s, deepFreeze(type));
3101
+ }
3172
3102
  return type;
3173
3103
  } catch (error) {
3174
3104
  throw new Error(
@@ -3243,19 +3173,54 @@ var Compile = (() => {
3243
3173
  color: [],
3244
3174
  expression: EXPRESSION_TYPES
3245
3175
  };
3176
+ var PRIMITIVE_SUBTYPES_CLOSURE = (() => {
3177
+ const closure = {};
3178
+ const closeOver = (t) => {
3179
+ if (closure[t]) return closure[t];
3180
+ const result = /* @__PURE__ */ new Set([t]);
3181
+ closure[t] = result;
3182
+ for (const sub2 of PRIMITIVE_SUBTYPES[t]) {
3183
+ if (sub2 === t) continue;
3184
+ for (const s of closeOver(sub2)) result.add(s);
3185
+ }
3186
+ return result;
3187
+ };
3188
+ for (const t of Object.keys(PRIMITIVE_SUBTYPES))
3189
+ closeOver(t);
3190
+ return closure;
3191
+ })();
3246
3192
  function isPrimitiveSubtype(lhs, rhs) {
3247
3193
  if (rhs === "any") return true;
3248
3194
  if (lhs === "never") return true;
3249
3195
  if (lhs === "unknown" || rhs === "unknown") return false;
3250
3196
  if (lhs === rhs) return true;
3251
- return PRIMITIVE_SUBTYPES[rhs].includes(lhs);
3197
+ return PRIMITIVE_SUBTYPES_CLOSURE[rhs].has(lhs);
3198
+ }
3199
+ function meetPrimitiveTypes(a, b) {
3200
+ if (a === b) return [a];
3201
+ const sa = PRIMITIVE_SUBTYPES_CLOSURE[a];
3202
+ const sb = PRIMITIVE_SUBTYPES_CLOSURE[b];
3203
+ if (sa.has(b)) return [b];
3204
+ if (sb.has(a)) return [a];
3205
+ const key = a < b ? `${a}|${b}` : `${b}|${a}`;
3206
+ const cached = MEET_CACHE.get(key);
3207
+ if (cached) return cached;
3208
+ const common = [];
3209
+ for (const t of sa) if (sb.has(t)) common.push(t);
3210
+ const maximals = common.filter(
3211
+ (t) => !common.some((u) => u !== t && PRIMITIVE_SUBTYPES_CLOSURE[u].has(t))
3212
+ );
3213
+ MEET_CACHE.set(key, maximals);
3214
+ return maximals;
3252
3215
  }
3216
+ var MEET_CACHE = /* @__PURE__ */ new Map();
3253
3217
  function isSubtype(lhs, rhs) {
3254
- if (typeof lhs === "string" && !PRIMITIVE_TYPES.includes(lhs))
3218
+ if (typeof lhs === "string" && !PRIMITIVE_TYPES_SET.has(lhs))
3255
3219
  lhs = parseType(lhs);
3256
- if (typeof rhs === "string" && !PRIMITIVE_TYPES.includes(rhs))
3220
+ if (typeof rhs === "string" && !PRIMITIVE_TYPES_SET.has(rhs))
3257
3221
  rhs = parseType(rhs);
3258
3222
  if (rhs === "any") return true;
3223
+ if (lhs === "never") return true;
3259
3224
  if (rhs === "never") return false;
3260
3225
  if (rhs === "error") return lhs === "error";
3261
3226
  if (rhs === "nothing") return lhs === "nothing";
@@ -3270,7 +3235,7 @@ var Compile = (() => {
3270
3235
  if (typeof lhs.value === "number") {
3271
3236
  if (Number.isInteger(lhs.value))
3272
3237
  return isPrimitiveSubtype("integer", rhs);
3273
- return isPrimitiveSubtype("number", rhs);
3238
+ return isPrimitiveSubtype("real", rhs);
3274
3239
  }
3275
3240
  if (typeof lhs.value === "boolean")
3276
3241
  return isPrimitiveSubtype("boolean", rhs);
@@ -3500,7 +3465,7 @@ var Compile = (() => {
3500
3465
  }
3501
3466
  function isNumeric(type) {
3502
3467
  if (typeof type === "string")
3503
- return NUMERIC_TYPES.includes(type);
3468
+ return NUMERIC_TYPES_SET.has(type);
3504
3469
  if (type.kind === "value") return typeof type.value === "number";
3505
3470
  if (type.kind === "numeric") return true;
3506
3471
  return false;
@@ -3508,7 +3473,7 @@ var Compile = (() => {
3508
3473
  function isScalar(type) {
3509
3474
  if (isNumeric(type)) return true;
3510
3475
  if (typeof type === "string")
3511
- return SCALAR_TYPES.includes(type);
3476
+ return SCALAR_TYPES_SET.has(type);
3512
3477
  if (type.kind === "value")
3513
3478
  return ["string", "boolean", "number"].includes(typeof type.value);
3514
3479
  return false;
@@ -3516,7 +3481,7 @@ var Compile = (() => {
3516
3481
  function isCollection(type) {
3517
3482
  if (isIndexedCollection(type)) return true;
3518
3483
  if (typeof type === "string")
3519
- return COLLECTION_TYPES.includes(type);
3484
+ return COLLECTION_TYPES_SET.has(type);
3520
3485
  return ["collection", "set", "record", "dictionary"].includes(type.kind);
3521
3486
  }
3522
3487
  function isIndexedCollection(type) {
@@ -3555,7 +3520,7 @@ var Compile = (() => {
3555
3520
  if (b === "unknown") return a;
3556
3521
  if (isSubtype(a, b)) return a;
3557
3522
  if (isSubtype(b, a)) return b;
3558
- return superType(a, b);
3523
+ return "never";
3559
3524
  }
3560
3525
  function widen2(a, b) {
3561
3526
  if (a === b) return a;
@@ -3589,16 +3554,17 @@ var Compile = (() => {
3589
3554
  ]);
3590
3555
  function unionTypes(a, b) {
3591
3556
  const members = [];
3557
+ const keys = /* @__PURE__ */ new Set();
3592
3558
  const push = (t) => {
3593
3559
  if (typeof t === "object" && t.kind === "union") {
3594
3560
  for (const m of t.types) push(m);
3595
3561
  return;
3596
3562
  }
3597
3563
  const key = typeof t === "string" ? t : JSON.stringify(t);
3598
- if (!members.some(
3599
- (m) => (typeof m === "string" ? m : JSON.stringify(m)) === key
3600
- ))
3564
+ if (!keys.has(key)) {
3565
+ keys.add(key);
3601
3566
  members.push(t);
3567
+ }
3602
3568
  };
3603
3569
  push(a);
3604
3570
  push(b);
@@ -3610,48 +3576,225 @@ var Compile = (() => {
3610
3576
  if (types.length === 1) return types[0];
3611
3577
  return types.reduce((a, b) => narrow2(a, b));
3612
3578
  }
3613
- function widen(...types) {
3614
- if (types.length === 0) return "nothing";
3615
- if (types.length === 1) return types[0];
3616
- return types.reduce((a, b) => widen2(a, b));
3579
+ function widen(...types) {
3580
+ if (types.length === 0) return "nothing";
3581
+ if (types.length === 1) return types[0];
3582
+ return types.reduce((a, b) => widen2(a, b));
3583
+ }
3584
+ var SUPERTYPE_PROBE_ORDER = [
3585
+ "non_finite_number",
3586
+ "finite_integer",
3587
+ "integer",
3588
+ "finite_rational",
3589
+ "rational",
3590
+ "finite_real",
3591
+ "real",
3592
+ "imaginary",
3593
+ "finite_complex",
3594
+ "complex",
3595
+ "finite_number",
3596
+ "number",
3597
+ "list",
3598
+ "record",
3599
+ "dictionary",
3600
+ "set",
3601
+ "tuple",
3602
+ "indexed_collection",
3603
+ "collection",
3604
+ "scalar",
3605
+ "value",
3606
+ "function",
3607
+ "expression"
3608
+ ];
3609
+ var PRIMITIVE_SUPERTYPE_CACHE = /* @__PURE__ */ new Map();
3610
+ function superType(a, b) {
3611
+ if (a === b) return a;
3612
+ if (a === "any" || b === "any") return "any";
3613
+ if (a === "never") return b;
3614
+ if (b === "never") return a;
3615
+ if (a === "unknown") return b;
3616
+ if (b === "unknown") return a;
3617
+ if (a === "nothing") return b;
3618
+ if (b === "nothing") return a;
3619
+ if (typeof a === "string" && typeof b === "string") {
3620
+ const key = a < b ? `${a}|${b}` : `${b}|${a}`;
3621
+ let result = PRIMITIVE_SUPERTYPE_CACHE.get(key);
3622
+ if (result === void 0) {
3623
+ result = "any";
3624
+ for (const ancestor of SUPERTYPE_PROBE_ORDER) {
3625
+ const subtypes = PRIMITIVE_SUBTYPES_CLOSURE[ancestor];
3626
+ if (subtypes.has(a) && subtypes.has(b)) {
3627
+ result = ancestor;
3628
+ break;
3629
+ }
3630
+ }
3631
+ PRIMITIVE_SUPERTYPE_CACHE.set(key, result);
3632
+ }
3633
+ return result;
3634
+ }
3635
+ for (const ancestor of SUPERTYPE_PROBE_ORDER)
3636
+ if (isSubtype(a, ancestor) && isSubtype(b, ancestor)) return ancestor;
3637
+ return "any";
3638
+ }
3639
+
3640
+ // src/common/type/serialize.ts
3641
+ var NEGATION_PRECEDENCE = 3;
3642
+ var UNION_PRECEDENCE = 1;
3643
+ var INTERSECTION_PRECEDENCE = 2;
3644
+ var LIST_PRECEDENCE = 4;
3645
+ var RECORD_PRECEDENCE = 5;
3646
+ var DICTIONARY_PRECEDENCE = 6;
3647
+ var SET_PRECEDENCE = 7;
3648
+ var COLLECTION_PRECEDENCE = 8;
3649
+ var TUPLE_PRECEDENCE = 9;
3650
+ var SIGNATURE_PRECEDENCE = 10;
3651
+ var VALUE_PRECEDENCE = 11;
3652
+ function typeToString(type, precedence = 0) {
3653
+ if (typeof type === "string") return type;
3654
+ let result = "";
3655
+ switch (type.kind) {
3656
+ case "value":
3657
+ if (typeof type.value === "string") result = `"${type.value}"`;
3658
+ else if (typeof type.value === "boolean")
3659
+ result = type.value ? "true" : "false";
3660
+ else result = type.value.toString();
3661
+ break;
3662
+ case "reference":
3663
+ result = type.name;
3664
+ break;
3665
+ case "negation":
3666
+ result = `!${typeToString(type.type, NEGATION_PRECEDENCE)}`;
3667
+ break;
3668
+ case "union":
3669
+ result = type.types.map((t) => typeToString(t, UNION_PRECEDENCE)).join(" | ");
3670
+ break;
3671
+ case "intersection":
3672
+ result = type.types.map((t) => typeToString(t, INTERSECTION_PRECEDENCE)).join(" & ");
3673
+ break;
3674
+ case "expression":
3675
+ result = `expression<${symbolName(type.operator)}>`;
3676
+ break;
3677
+ case "symbol":
3678
+ result = `symbol<${symbolName(type.name)}>`;
3679
+ break;
3680
+ case "numeric":
3681
+ if (Number.isFinite(type.lower) && Number.isFinite(type.upper)) {
3682
+ result = `${type.type}<${type.lower}..${type.upper}>`;
3683
+ } else if (Number.isFinite(type.lower)) {
3684
+ result = `${type.type}<${type.lower}..>`;
3685
+ } else if (Number.isFinite(type.upper)) {
3686
+ result = `${type.type}<..${type.upper}>`;
3687
+ } else {
3688
+ result = `${type.type}`;
3689
+ }
3690
+ break;
3691
+ case "list":
3692
+ if (type.dimensions && typeof type.elements === "string" && NUMERIC_TYPES_SET.has(type.elements)) {
3693
+ if (type.dimensions === void 0) {
3694
+ if (type.elements === "number") result = "tensor";
3695
+ } else if (type.dimensions.length === 1) {
3696
+ if (type.elements === "number") {
3697
+ if (type.dimensions[0] < 0) result = "vector";
3698
+ else result = `vector<${type.dimensions[0]}>`;
3699
+ } else {
3700
+ if (type.dimensions[0] < 0)
3701
+ result = `vector<${typeToString(type.elements)}>`;
3702
+ else
3703
+ result = `vector<${typeToString(type.elements)}^${type.dimensions[0]}>`;
3704
+ }
3705
+ } else if (type.dimensions.length === 2) {
3706
+ const dims = type.dimensions;
3707
+ if (type.elements === "number") {
3708
+ if (dims[0] < 0 && dims[1] < 0) result = "matrix";
3709
+ else result = `matrix<${dims[0]}x${dims[1]}>`;
3710
+ } else {
3711
+ if (dims[0] < 0 && dims[1] < 0)
3712
+ result = `matrix<${typeToString(type.elements)}>`;
3713
+ else
3714
+ result = `matrix<${typeToString(type.elements)}^(${dims[0]}x${dims[1]})>`;
3715
+ }
3716
+ }
3717
+ }
3718
+ if (!result) {
3719
+ const dimensions = type.dimensions ? type.dimensions.length === 1 ? `^${type.dimensions[0].toString()}` : `^(${type.dimensions.join("x")})` : "";
3720
+ result = `list<${typeToString(type.elements)}${dimensions}>`;
3721
+ }
3722
+ break;
3723
+ case "record":
3724
+ const elements = Object.entries(type.elements).map(([key, value]) => `${key}: ${typeToString(value)}`).join(", ");
3725
+ result = `record<${elements}>`;
3726
+ break;
3727
+ case "dictionary":
3728
+ result = `dictionary<${typeToString(type.values)}>`;
3729
+ break;
3730
+ case "set":
3731
+ result = `set<${typeToString(type.elements)}>`;
3732
+ break;
3733
+ case "collection":
3734
+ result = `collection<${typeToString(type.elements)}>`;
3735
+ break;
3736
+ case "indexed_collection":
3737
+ result = `indexed_collection<${typeToString(type.elements)}>`;
3738
+ break;
3739
+ case "tuple":
3740
+ if (type.elements.length === 0) result = "tuple";
3741
+ else if (type.elements.length === 1) {
3742
+ const [el] = type.elements;
3743
+ result = `tuple<${namedElement(el)}>`;
3744
+ } else {
3745
+ result = "tuple<" + type.elements.map((el) => namedElement(el)).join(", ") + ">";
3746
+ }
3747
+ break;
3748
+ case "signature":
3749
+ const args = type.args ? type.args.map((arg) => namedElement(arg)).join(", ") : "";
3750
+ const optArgs = type.optArgs ? type.optArgs.map((arg) => namedElement(arg) + "?").join(", ") : "";
3751
+ const varArg = type.variadicArg ? type.variadicMin === 0 ? `${namedElement(type.variadicArg)}*` : `${namedElement(type.variadicArg)}+` : "";
3752
+ const argsList = [args, optArgs, varArg].filter((s) => s).join(", ");
3753
+ result = `(${argsList}) -> ${typeToString(type.result)}`;
3754
+ break;
3755
+ default:
3756
+ result = "error";
3757
+ }
3758
+ if (precedence > 0 && precedence > getPrecedence(type.kind))
3759
+ return `(${result})`;
3760
+ return result;
3761
+ }
3762
+ function namedElement(el) {
3763
+ if (el.name) return `${el.name}: ${typeToString(el.type)}`;
3764
+ return typeToString(el.type);
3617
3765
  }
3618
- function superType(a, b) {
3619
- if (a === b) return a;
3620
- if (a === "any" || b === "any") return "any";
3621
- if (a === "never") return b;
3622
- if (b === "never") return a;
3623
- if (a === "unknown") return b;
3624
- if (b === "unknown") return a;
3625
- if (a === "nothing") return b;
3626
- if (b === "nothing") return a;
3627
- if (commonSupertype(a, b, "non_finite_number")) return "non_finite_number";
3628
- if (commonSupertype(a, b, "finite_integer")) return "finite_integer";
3629
- if (commonSupertype(a, b, "integer")) return "integer";
3630
- if (commonSupertype(a, b, "finite_rational")) return "finite_rational";
3631
- if (commonSupertype(a, b, "rational")) return "rational";
3632
- if (commonSupertype(a, b, "finite_real")) return "finite_real";
3633
- if (commonSupertype(a, b, "real")) return "real";
3634
- if (commonSupertype(a, b, "imaginary")) return "imaginary";
3635
- if (commonSupertype(a, b, "finite_complex")) return "finite_complex";
3636
- if (commonSupertype(a, b, "complex")) return "complex";
3637
- if (commonSupertype(a, b, "finite_number")) return "finite_number";
3638
- if (commonSupertype(a, b, "number")) return "number";
3639
- if (commonSupertype(a, b, "list")) return "list";
3640
- if (commonSupertype(a, b, "record")) return "record";
3641
- if (commonSupertype(a, b, "dictionary")) return "dictionary";
3642
- if (commonSupertype(a, b, "set")) return "set";
3643
- if (commonSupertype(a, b, "tuple")) return "tuple";
3644
- if (commonSupertype(a, b, "indexed_collection")) return "indexed_collection";
3645
- if (commonSupertype(a, b, "collection")) return "collection";
3646
- if (commonSupertype(a, b, "scalar")) return "scalar";
3647
- if (commonSupertype(a, b, "value")) return "value";
3648
- if (commonSupertype(a, b, "function")) return "function";
3649
- if (commonSupertype(a, b, "expression")) return "expression";
3650
- return "any";
3766
+ function symbolName(name) {
3767
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) return name;
3768
+ return `\`${name}\``;
3651
3769
  }
3652
- function commonSupertype(a, b, ancestor) {
3653
- if (isSubtype(a, ancestor) && isSubtype(b, ancestor)) return true;
3654
- return false;
3770
+ function getPrecedence(kind) {
3771
+ switch (kind) {
3772
+ case "negation":
3773
+ return NEGATION_PRECEDENCE;
3774
+ case "union":
3775
+ return UNION_PRECEDENCE;
3776
+ case "intersection":
3777
+ return INTERSECTION_PRECEDENCE;
3778
+ case "list":
3779
+ return LIST_PRECEDENCE;
3780
+ case "record":
3781
+ return RECORD_PRECEDENCE;
3782
+ case "dictionary":
3783
+ return DICTIONARY_PRECEDENCE;
3784
+ case "set":
3785
+ return SET_PRECEDENCE;
3786
+ case "collection":
3787
+ case "indexed_collection":
3788
+ return COLLECTION_PRECEDENCE;
3789
+ case "tuple":
3790
+ return TUPLE_PRECEDENCE;
3791
+ case "signature":
3792
+ return SIGNATURE_PRECEDENCE;
3793
+ case "value":
3794
+ return VALUE_PRECEDENCE;
3795
+ default:
3796
+ return 0;
3797
+ }
3655
3798
  }
3656
3799
 
3657
3800
  // src/common/type/utils.ts
@@ -3760,6 +3903,12 @@ var Compile = (() => {
3760
3903
  return expr?._kind === "symbol" ? expr.symbol : void 0;
3761
3904
  }
3762
3905
 
3906
+ // src/compute-engine/boxed-expression/constraint-subject.ts
3907
+ var EMPTY_FACT_INDEX = Object.freeze({
3908
+ bySubject: /* @__PURE__ */ new Map(),
3909
+ membership: /* @__PURE__ */ new Map()
3910
+ });
3911
+
3763
3912
  // src/compute-engine/boxed-expression/stochastic-equal.ts
3764
3913
  var WELL_KNOWN_POINTS = [
3765
3914
  0,
@@ -4008,6 +4157,7 @@ var Compile = (() => {
4008
4157
  }
4009
4158
 
4010
4159
  // src/compute-engine/collection-utils.ts
4160
+ var MAX_SIZE_EAGER_COLLECTION = 100;
4011
4161
  function isFiniteIndexedCollection(col) {
4012
4162
  return (col.isFiniteCollection ?? false) && col.isIndexedCollection;
4013
4163
  }
@@ -4636,12 +4786,14 @@ var Compile = (() => {
4636
4786
  if (expr === null) return null;
4637
4787
  if (isDictionaryObject(expr)) return expr;
4638
4788
  const kv = keyValuePair(expr);
4639
- if (kv) return { [kv[0]]: kv[1] };
4789
+ if (kv)
4790
+ return {
4791
+ dict: { [kv[0]]: expressionToDictionaryValue(kv[1]) ?? "Nothing" }
4792
+ };
4640
4793
  if (operator(expr) === "Dictionary") {
4641
4794
  const dict = {};
4642
- const ops = operands(expr);
4643
- for (let i = 1; i < nops(expr); i++) {
4644
- const kv2 = keyValuePair(ops[i]);
4795
+ for (const op of operands(expr)) {
4796
+ const kv2 = keyValuePair(op);
4645
4797
  if (kv2) {
4646
4798
  dict[kv2[0]] = expressionToDictionaryValue(kv2[1]) ?? "Nothing";
4647
4799
  }
@@ -6575,6 +6727,7 @@ var Compile = (() => {
6575
6727
  }
6576
6728
  }
6577
6729
  if (!variable) return null;
6730
+ if (symbol(variable) === null) return null;
6578
6731
  parser.skipSpace();
6579
6732
  const fn = parser.parseExpression({ minPrec: 740 });
6580
6733
  if (!fn) return null;
@@ -6761,7 +6914,7 @@ var Compile = (() => {
6761
6914
  if (runs.length === 1) body = runs[0];
6762
6915
  else {
6763
6916
  if (runs.every((x) => stringValue(x) !== null))
6764
- body = "'" + runs.map((x) => stringValue(x)).join() + "'";
6917
+ body = "'" + runs.map((x) => stringValue(x)).join("") + "'";
6765
6918
  else body = ["Text", ...runs];
6766
6919
  }
6767
6920
  return style ? ["Annotated", body, dictionaryFromEntries(style)] : body;
@@ -8294,6 +8447,8 @@ var Compile = (() => {
8294
8447
  const h = operator(arg);
8295
8448
  if (prevWasNumber && (h === "Divide" || h === "Rational")) {
8296
8449
  result = latexTemplate(serializer.options.multiply, result, term);
8450
+ } else if (/^\d/.test(term)) {
8451
+ result = latexTemplate(serializer.options.multiply, result, term);
8297
8452
  } else if (!serializer.options.invisibleMultiply) {
8298
8453
  result = joinLatex([result, term]);
8299
8454
  } else {
@@ -9739,7 +9894,8 @@ var Compile = (() => {
9739
9894
  minPrec: MULTIPLICATION_PRECEDENCE,
9740
9895
  condition: (parser2) => trigCommands[parser2.peek] || (until?.condition?.(parser2) ?? false)
9741
9896
  });
9742
- const head = fn === "Arctan" && args?.length === 2 ? "Arctan2" : fn;
9897
+ const isTwoArgArctan = args?.length === 2 && (fn === "Arctan" || Array.isArray(fn) && fn[0] === "InverseFunction" && fn[1] === "Tan");
9898
+ const head = isTwoArgArctan ? "Arctan2" : fn;
9743
9899
  const appliedFn = args === null ? fn : typeof head === "string" ? [head, ...args] : ["Apply", head, ...args];
9744
9900
  return sup === null ? appliedFn : ["Power", appliedFn, sup];
9745
9901
  };
@@ -12026,6 +12182,30 @@ var Compile = (() => {
12026
12182
  var SOME_EMOJI = new RegExp(`(?:${POSSIBLE_EMOJI})+`, "u");
12027
12183
  var EMOJIS = new RegExp(`^(?:${POSSIBLE_EMOJI})+$`, "u");
12028
12184
 
12185
+ // src/compute-engine/latex-syntax/parse.ts
12186
+ var PARSE_TOKEN_EXCLUDED = /* @__PURE__ */ new Set([
12187
+ ...'!"#$%&(),/;:?@[]\\`|~'.split(""),
12188
+ "\\left",
12189
+ "\\bigl",
12190
+ "\\mleft"
12191
+ ]);
12192
+ var TEX_UNIT_TOKENS = [
12193
+ "pt",
12194
+ "em",
12195
+ "mu",
12196
+ "ex",
12197
+ "mm",
12198
+ "cm",
12199
+ "in",
12200
+ "bp",
12201
+ "sp",
12202
+ "dd",
12203
+ "cc",
12204
+ "pc",
12205
+ "nc",
12206
+ "nd"
12207
+ ].map((unit) => [...unit]);
12208
+
12029
12209
  // src/compute-engine/boxed-expression/utils.ts
12030
12210
  function isValueDef(def) {
12031
12211
  return def !== void 0 && "value" in def;
@@ -12061,6 +12241,50 @@ var Compile = (() => {
12061
12241
  return ys;
12062
12242
  }
12063
12243
 
12244
+ // src/common/fuzzy-string-match.ts
12245
+ function levenshtein(source, target) {
12246
+ if (source === target) return 0;
12247
+ if (source.length === 0) return target.length;
12248
+ if (target.length === 0) return source.length;
12249
+ let prevRow = Array.from(
12250
+ { length: source.length + 1 },
12251
+ (_, j) => j
12252
+ );
12253
+ let currRow = new Array(source.length + 1);
12254
+ for (let i = 1; i <= target.length; i++) {
12255
+ currRow[0] = i;
12256
+ for (let j = 1; j <= source.length; j++) {
12257
+ const cost = source[j - 1] === target[i - 1] ? 0 : 1;
12258
+ currRow[j] = Math.min(
12259
+ prevRow[j] + 1,
12260
+ // deletion
12261
+ currRow[j - 1] + 1,
12262
+ // insertion
12263
+ prevRow[j - 1] + cost
12264
+ // substitution
12265
+ );
12266
+ }
12267
+ [prevRow, currRow] = [currRow, prevRow];
12268
+ }
12269
+ return prevRow[source.length];
12270
+ }
12271
+ function fuzzyStringMatch(invalidWord, validWords) {
12272
+ const threshold = 7;
12273
+ let bestMatch = null;
12274
+ let minDistance = Infinity;
12275
+ const invalidLength = invalidWord.length;
12276
+ for (const word of validWords) {
12277
+ if (Math.abs(invalidLength - word.length) > threshold) continue;
12278
+ const distance = levenshtein(invalidWord, word);
12279
+ if (distance === 0) return word;
12280
+ if (distance <= threshold && distance < minDistance) {
12281
+ minDistance = distance;
12282
+ bestMatch = word;
12283
+ }
12284
+ }
12285
+ return bestMatch;
12286
+ }
12287
+
12064
12288
  // src/compute-engine/boxed-expression/validate.ts
12065
12289
  function checkArity(ce, ops, count) {
12066
12290
  ops = flatten(ops);
@@ -12992,21 +13216,249 @@ ${lines.join("\n")}`;
12992
13216
  isInfinite() {
12993
13217
  return !(this["isNaN"]() || this["isFinite"]());
12994
13218
  }
12995
- };
12996
- Complex["ZERO"] = new Complex(0, 0);
12997
- Complex["ONE"] = new Complex(1, 0);
12998
- Complex["I"] = new Complex(0, 1);
12999
- Complex["PI"] = new Complex(Math.PI, 0);
13000
- Complex["E"] = new Complex(Math.E, 0);
13001
- Complex["INFINITY"] = new Complex(Infinity, Infinity);
13002
- Complex["NAN"] = new Complex(NaN, NaN);
13003
- Complex["EPSILON"] = 1e-15;
13004
-
13005
- // src/compute-engine/boxed-expression/numerics.ts
13006
- function toInteger(expr) {
13007
- if (!isNumber(expr)) return null;
13008
- const num = expr.numericValue;
13009
- return Math.round(typeof num === "number" ? num : num.re);
13219
+ };
13220
+ Complex["ZERO"] = new Complex(0, 0);
13221
+ Complex["ONE"] = new Complex(1, 0);
13222
+ Complex["I"] = new Complex(0, 1);
13223
+ Complex["PI"] = new Complex(Math.PI, 0);
13224
+ Complex["E"] = new Complex(Math.E, 0);
13225
+ Complex["INFINITY"] = new Complex(Infinity, Infinity);
13226
+ Complex["NAN"] = new Complex(NaN, NaN);
13227
+ Complex["EPSILON"] = 1e-15;
13228
+
13229
+ // src/compute-engine/boxed-expression/numerics.ts
13230
+ function asSmallInteger(expr) {
13231
+ if (expr === void 0 || expr === null) return null;
13232
+ if (typeof expr === "number") {
13233
+ if (Number.isInteger(expr) && expr >= -SMALL_INTEGER && expr <= SMALL_INTEGER)
13234
+ return expr;
13235
+ return null;
13236
+ }
13237
+ if (!isNumber(expr)) return null;
13238
+ const num = expr.numericValue;
13239
+ if (typeof num === "number") {
13240
+ if (Number.isInteger(num) && num >= -SMALL_INTEGER && num <= SMALL_INTEGER)
13241
+ return num;
13242
+ return null;
13243
+ }
13244
+ if (num.im !== 0) return null;
13245
+ const n = num.re;
13246
+ if (Number.isInteger(n) && n >= -SMALL_INTEGER && n <= SMALL_INTEGER)
13247
+ return Number(n);
13248
+ return null;
13249
+ }
13250
+ function toInteger(expr) {
13251
+ if (!isNumber(expr)) return null;
13252
+ const num = expr.numericValue;
13253
+ return Math.round(typeof num === "number" ? num : num.re);
13254
+ }
13255
+
13256
+ // src/compute-engine/library/logic-analysis.ts
13257
+ function filterValuesWithCondition(values, variable, conditionExpr, _ce) {
13258
+ return values.filter((value) => {
13259
+ const substituted = conditionExpr.subs({ [variable]: value });
13260
+ const result = substituted.evaluate();
13261
+ return sym(result) === "True";
13262
+ });
13263
+ }
13264
+ function extractFiniteDomainWithReason(condition, ce) {
13265
+ if (condition.operator !== "Element") {
13266
+ return { status: "error", reason: "expected-element-expression" };
13267
+ }
13268
+ if (!isFunction2(condition)) {
13269
+ return { status: "error", reason: "expected-element-expression" };
13270
+ }
13271
+ const variable = isSymbol2(condition.op1) ? condition.op1.symbol : void 0;
13272
+ if (!variable) {
13273
+ return { status: "error", reason: "expected-index-variable" };
13274
+ }
13275
+ const domain = condition.op2;
13276
+ if (!domain) {
13277
+ return { status: "error", reason: "expected-domain" };
13278
+ }
13279
+ const maybeCondition = condition.op3;
13280
+ const filterCondition = condition.nops >= 3 && maybeCondition && sym(maybeCondition) !== "Nothing" ? maybeCondition : null;
13281
+ const successResult = (values) => {
13282
+ if (filterCondition) {
13283
+ const filteredValues = filterValuesWithCondition(
13284
+ values,
13285
+ variable,
13286
+ filterCondition,
13287
+ ce
13288
+ );
13289
+ return { status: "success", variable, values: filteredValues };
13290
+ }
13291
+ return { status: "success", variable, values };
13292
+ };
13293
+ if (domain.operator === "Set" || domain.operator === "List") {
13294
+ const values = isFunction2(domain) ? domain.ops : void 0;
13295
+ if (values && values.length <= 1e3) {
13296
+ if (domain.operator === "List" && values.length === 2) {
13297
+ const start = asSmallInteger(values[0]);
13298
+ const end = asSmallInteger(values[1]);
13299
+ if (start !== null && end !== null) {
13300
+ const count = end - start + 1;
13301
+ if (count > 0 && count <= 1e3) {
13302
+ const rangeValues = [];
13303
+ for (let i = start; i <= end; i++) {
13304
+ rangeValues.push(ce.number(i));
13305
+ }
13306
+ return successResult(rangeValues);
13307
+ }
13308
+ if (count > 1e3) {
13309
+ return {
13310
+ status: "non-enumerable",
13311
+ variable,
13312
+ domain,
13313
+ reason: "domain-too-large"
13314
+ };
13315
+ }
13316
+ }
13317
+ }
13318
+ return successResult([...values]);
13319
+ }
13320
+ if (values && values.length > 1e3) {
13321
+ return {
13322
+ status: "non-enumerable",
13323
+ variable,
13324
+ domain,
13325
+ reason: "domain-too-large"
13326
+ };
13327
+ }
13328
+ return { status: "error", reason: "empty-domain" };
13329
+ }
13330
+ if (isFunction2(domain, "Range")) {
13331
+ const start = asSmallInteger(domain.op1);
13332
+ const end = asSmallInteger(domain.op2);
13333
+ const step = domain.ops.length >= 3 ? asSmallInteger(domain.op3) : 1;
13334
+ if (start !== null && end !== null && step !== null && step !== 0) {
13335
+ const count = Math.floor((end - start) / step) + 1;
13336
+ if (count > 0 && count <= 1e3) {
13337
+ const values = [];
13338
+ for (let i = start; step > 0 ? i <= end : i >= end; i += step) {
13339
+ values.push(ce.number(i));
13340
+ }
13341
+ return successResult(values);
13342
+ }
13343
+ if (count > 1e3) {
13344
+ return {
13345
+ status: "non-enumerable",
13346
+ variable,
13347
+ domain,
13348
+ reason: "domain-too-large"
13349
+ };
13350
+ }
13351
+ }
13352
+ return {
13353
+ status: "non-enumerable",
13354
+ variable,
13355
+ domain,
13356
+ reason: "non-integer-bounds"
13357
+ };
13358
+ }
13359
+ if (isFunction2(domain, "Interval")) {
13360
+ let op1 = domain.op1;
13361
+ let op2 = domain.op2;
13362
+ let openStart = false;
13363
+ let openEnd = false;
13364
+ if (isFunction2(op1, "Open")) {
13365
+ openStart = true;
13366
+ op1 = op1.op1;
13367
+ } else if (isFunction2(op1, "Closed")) {
13368
+ op1 = op1.op1;
13369
+ }
13370
+ if (isFunction2(op2, "Open")) {
13371
+ openEnd = true;
13372
+ op2 = op2.op1;
13373
+ } else if (isFunction2(op2, "Closed")) {
13374
+ op2 = op2.op1;
13375
+ }
13376
+ let start = asSmallInteger(op1);
13377
+ let end = asSmallInteger(op2);
13378
+ if (start !== null && end !== null) {
13379
+ if (openStart) start += 1;
13380
+ if (openEnd) end -= 1;
13381
+ const count = end - start + 1;
13382
+ if (count > 0 && count <= 1e3) {
13383
+ const values = [];
13384
+ for (let i = start; i <= end; i++) {
13385
+ values.push(ce.number(i));
13386
+ }
13387
+ return successResult(values);
13388
+ }
13389
+ if (count > 1e3) {
13390
+ return {
13391
+ status: "non-enumerable",
13392
+ variable,
13393
+ domain,
13394
+ reason: "domain-too-large"
13395
+ };
13396
+ }
13397
+ }
13398
+ return {
13399
+ status: "non-enumerable",
13400
+ variable,
13401
+ domain,
13402
+ reason: "non-integer-bounds"
13403
+ };
13404
+ }
13405
+ const domainSymbol = sym(domain);
13406
+ if (domainSymbol) {
13407
+ const knownInfiniteSets = [
13408
+ "Integers",
13409
+ "NonNegativeIntegers",
13410
+ "PositiveIntegers",
13411
+ "NegativeIntegers",
13412
+ "Rationals",
13413
+ "Reals",
13414
+ "PositiveReals",
13415
+ "NonNegativeReals",
13416
+ "NegativeReals",
13417
+ "NonPositiveReals",
13418
+ "ExtendedReals",
13419
+ "Complexes",
13420
+ "ImaginaryNumbers",
13421
+ "Numbers",
13422
+ "ExtendedComplexes",
13423
+ "AlgebraicNumbers",
13424
+ "TranscendentalNumbers"
13425
+ ];
13426
+ if (knownInfiniteSets.includes(domainSymbol)) {
13427
+ return {
13428
+ status: "non-enumerable",
13429
+ variable,
13430
+ domain,
13431
+ reason: "infinite-domain"
13432
+ };
13433
+ }
13434
+ const domainValue = domain.value;
13435
+ if (domainValue && domainValue.operator === "Set" && isFunction2(domainValue)) {
13436
+ const values = domainValue.ops;
13437
+ if (values && values.length <= 1e3) {
13438
+ return successResult([...values]);
13439
+ }
13440
+ if (values && values.length > 1e3) {
13441
+ return {
13442
+ status: "non-enumerable",
13443
+ variable,
13444
+ domain,
13445
+ reason: "domain-too-large"
13446
+ };
13447
+ }
13448
+ }
13449
+ return {
13450
+ status: "non-enumerable",
13451
+ variable,
13452
+ domain,
13453
+ reason: "unknown-domain"
13454
+ };
13455
+ }
13456
+ return {
13457
+ status: "non-enumerable",
13458
+ variable,
13459
+ domain,
13460
+ reason: "unrecognized-domain-type"
13461
+ };
13010
13462
  }
13011
13463
 
13012
13464
  // src/compute-engine/numerics/interval.ts
@@ -13063,6 +13515,11 @@ ${lines.join("\n")}`;
13063
13515
  }
13064
13516
  return void 0;
13065
13517
  }
13518
+ function intervalContains(int, val) {
13519
+ if (int.openStart ? val <= int.start : val < int.start) return false;
13520
+ if (int.openEnd ? val >= int.end : val > int.end) return false;
13521
+ return true;
13522
+ }
13066
13523
 
13067
13524
  // src/compute-engine/numerics/random.ts
13068
13525
  function deterministicRandom(seed) {
@@ -13079,8 +13536,236 @@ ${lines.join("\n")}`;
13079
13536
  return xs.map((x) => ce.expr(x, { scope }));
13080
13537
  }
13081
13538
 
13539
+ // src/common/type/reduce.ts
13540
+ function reduceType(type) {
13541
+ if (typeof type === "string") {
13542
+ if (!isValidPrimitiveType(type)) return "error";
13543
+ return type;
13544
+ }
13545
+ switch (type.kind) {
13546
+ case "union":
13547
+ return reduceUnionType(type);
13548
+ case "intersection":
13549
+ return reduceIntersectionType(type);
13550
+ case "negation":
13551
+ return reduceNegationType(type);
13552
+ case "collection":
13553
+ case "indexed_collection":
13554
+ return reduceCollectionType(type.kind, type);
13555
+ case "list":
13556
+ return reduceListType(type);
13557
+ case "set":
13558
+ return reduceSetType(type);
13559
+ case "tuple":
13560
+ return reduceTupleType(type);
13561
+ case "record":
13562
+ return reduceRecordType(type);
13563
+ case "dictionary":
13564
+ return reduceDictionaryType(type);
13565
+ case "signature":
13566
+ return reduceSignatureType(type);
13567
+ case "value":
13568
+ return type;
13569
+ case "reference":
13570
+ return type;
13571
+ default:
13572
+ throw new Error(`Unknown type kind: ${type}`);
13573
+ }
13574
+ }
13575
+ function decorate(t) {
13576
+ if (typeof t !== "object") return t;
13577
+ if (Object.isFrozen(t) || Object.prototype.hasOwnProperty.call(t, "toString"))
13578
+ return t;
13579
+ Object.defineProperty(t, "toString", { value: () => typeToString(t) });
13580
+ return t;
13581
+ }
13582
+ function reduceMembers(types) {
13583
+ const result = [];
13584
+ const seen = /* @__PURE__ */ new Set();
13585
+ for (const t of types) {
13586
+ const reduced = reduceType(t);
13587
+ const key = typeof reduced === "string" ? reduced : typeToString(reduced);
13588
+ if (!seen.has(key)) {
13589
+ seen.add(key);
13590
+ result.push(reduced);
13591
+ }
13592
+ }
13593
+ return result;
13594
+ }
13595
+ function reduceNegationType(type) {
13596
+ const reducedType = reduceType(type.type);
13597
+ if (reducedType === "nothing") return "any";
13598
+ if (reducedType === "any") return "nothing";
13599
+ return decorate({ kind: "negation", type: reducedType });
13600
+ }
13601
+ function reduceUnionType(type) {
13602
+ const reducedTypes = reduceMembers(type.types);
13603
+ if (reducedTypes.length === 0) return "never";
13604
+ if (reducedTypes.some((type2) => type2 === "error")) return "error";
13605
+ if (reducedTypes.length === 1) return decorate(reducedTypes[0]);
13606
+ const acc = [];
13607
+ for (const current of reducedTypes) {
13608
+ if (acc.some((t) => isSubtype(current, t))) continue;
13609
+ for (let i = acc.length - 1; i >= 0; i--)
13610
+ if (isSubtype(acc[i], current)) acc.splice(i, 1);
13611
+ acc.push(current);
13612
+ }
13613
+ if (acc.length === 1) return decorate(acc[0]);
13614
+ return decorate({ kind: "union", types: acc });
13615
+ }
13616
+ function meet2(a, b) {
13617
+ if (isSubtype(a, b)) return a;
13618
+ if (isSubtype(b, a)) return b;
13619
+ if (typeof a === "object" && a.kind === "union") return meetUnion(a.types, b);
13620
+ if (typeof b === "object" && b.kind === "union") return meetUnion(b.types, a);
13621
+ if (typeof a === "string" && typeof b === "string") {
13622
+ const maximals = meetPrimitiveTypes(a, b);
13623
+ if (maximals.length === 0) return "nothing";
13624
+ if (maximals.length === 1) return maximals[0];
13625
+ return { kind: "union", types: maximals };
13626
+ }
13627
+ return "nothing";
13628
+ }
13629
+ function meetUnion(types, b) {
13630
+ const members = types.map((t) => meet2(t, b)).filter((t) => t !== "nothing");
13631
+ if (members.length === 0) return "nothing";
13632
+ if (members.length === 1) return members[0];
13633
+ return reduceUnionType({ kind: "union", types: members });
13634
+ }
13635
+ function reduceIntersectionType(type) {
13636
+ const reducedTypes = reduceMembers(type.types);
13637
+ if (reducedTypes.length === 0) return "nothing";
13638
+ if (reducedTypes.some((type2) => type2 === "error")) return "error";
13639
+ let result = reducedTypes[0];
13640
+ for (let i = 1; i < reducedTypes.length; i++) {
13641
+ result = meet2(result, reducedTypes[i]);
13642
+ if (result === "nothing") return "nothing";
13643
+ }
13644
+ return decorate(result);
13645
+ }
13646
+ function reduceCollectionType(kind, type) {
13647
+ const reducedType = reduceType(type.elements);
13648
+ if (reducedType === "error") return "error";
13649
+ if (reducedType === "nothing") return decorate({ kind, elements: "nothing" });
13650
+ if (reducedType === "any") return kind;
13651
+ return decorate({
13652
+ ...type,
13653
+ elements: reducedType
13654
+ });
13655
+ }
13656
+ function reduceListType(type) {
13657
+ const reducedType = reduceType(type.elements);
13658
+ if (reducedType === "error") return "error";
13659
+ if (reducedType === "nothing")
13660
+ return decorate({ kind: "list", elements: "nothing" });
13661
+ if (reducedType === "any") return "list";
13662
+ let dimensions = type.dimensions;
13663
+ if (dimensions) {
13664
+ dimensions = dimensions.filter((dim) => dim >= 1 || dim === -1);
13665
+ if (dimensions.length === 0) return "nothing";
13666
+ }
13667
+ return decorate({
13668
+ ...type,
13669
+ dimensions,
13670
+ elements: reducedType
13671
+ });
13672
+ }
13673
+ function reduceSetType(type) {
13674
+ const reducedType = reduceType(type.elements);
13675
+ if (reducedType === "error") return "error";
13676
+ if (reducedType === "nothing")
13677
+ return decorate({ kind: "set", elements: "nothing" });
13678
+ if (reducedType === "any") return "set";
13679
+ return decorate({
13680
+ ...type,
13681
+ elements: reducedType
13682
+ });
13683
+ }
13684
+ function reduceTupleType(type) {
13685
+ let reducedElements = type.elements.map((element) => ({
13686
+ ...element,
13687
+ type: reduceType(element.type)
13688
+ }));
13689
+ if (reducedElements.length === 0) return "nothing";
13690
+ if (reducedElements.some((element) => element.type === "error"))
13691
+ return "error";
13692
+ reducedElements = reducedElements.filter(
13693
+ (element) => element.type !== "nothing"
13694
+ );
13695
+ return decorate({
13696
+ ...type,
13697
+ elements: reducedElements
13698
+ });
13699
+ }
13700
+ function reduceRecordType(type) {
13701
+ let reducedElements = {};
13702
+ for (const [key, value] of Object.entries(type.elements))
13703
+ reducedElements[key] = reduceType(value);
13704
+ if (Object.values(reducedElements).some((type2) => type2 === "error"))
13705
+ return "error";
13706
+ reducedElements = Object.fromEntries(
13707
+ Object.entries(reducedElements).filter(([_, value]) => value !== "nothing")
13708
+ );
13709
+ if (Object.keys(reducedElements).length === 0) return "record";
13710
+ return decorate({
13711
+ ...type,
13712
+ elements: reducedElements
13713
+ });
13714
+ }
13715
+ function reduceDictionaryType(type) {
13716
+ const reducedValues = reduceType(type.values);
13717
+ if (reducedValues === "error") return "error";
13718
+ if (reducedValues === "nothing") return "error";
13719
+ if (reducedValues === "any" || reducedValues === "unknown") return "any";
13720
+ return decorate({ kind: "dictionary", values: reducedValues });
13721
+ }
13722
+ function reduceSignatureType(type) {
13723
+ const reducedArgs = type.args?.map((arg) => ({
13724
+ ...arg,
13725
+ type: reduceType(arg.type)
13726
+ }));
13727
+ let reducedOptArgs = type.optArgs?.map((arg) => ({
13728
+ ...arg,
13729
+ type: reduceType(arg.type)
13730
+ }));
13731
+ let reducedVarArg = type.variadicArg ? {
13732
+ ...type.variadicArg,
13733
+ type: reduceType(type.variadicArg.type)
13734
+ } : void 0;
13735
+ const reducedResult = reduceType(type.result);
13736
+ if (reducedArgs?.some((arg) => arg.type === "error")) return "error";
13737
+ if (reducedOptArgs?.some((arg) => arg.type === "error")) return "error";
13738
+ if (reducedVarArg?.type === "error") return "error";
13739
+ if (reducedResult === "error") return "error";
13740
+ reducedOptArgs = reducedOptArgs?.filter((arg) => arg.type !== "nothing");
13741
+ if (reducedArgs?.length === 0) reducedOptArgs = void 0;
13742
+ if (reducedOptArgs?.length === 0) reducedOptArgs = void 0;
13743
+ if (reducedVarArg?.type === "nothing") reducedVarArg = void 0;
13744
+ return decorate({
13745
+ ...type,
13746
+ args: reducedArgs,
13747
+ optArgs: reducedOptArgs,
13748
+ variadicArg: reducedVarArg,
13749
+ variadicMin: reducedVarArg ? type.variadicMin : void 0,
13750
+ result: reducedResult
13751
+ });
13752
+ }
13753
+
13754
+ // src/compute-engine/library/sets.ts
13755
+ function typeIntersection(a, b) {
13756
+ return reduceType({ kind: "intersection", types: [a, b] });
13757
+ }
13758
+ function typeMembership(x, t) {
13759
+ const vt = x.type;
13760
+ if (vt.matches(t)) return true;
13761
+ if (typeIntersection(vt.type, t) === "nothing") return false;
13762
+ if (isNumber(x)) return false;
13763
+ return void 0;
13764
+ }
13765
+
13082
13766
  // src/compute-engine/library/collections.ts
13083
13767
  var DEFAULT_LINSPACE_COUNT = 50;
13768
+ var SET_BASE_HANDLERS = basicIndexedCollectionHandlers();
13084
13769
  var COLLECTIONS_LIBRARY = {
13085
13770
  //
13086
13771
  // Data Structures
@@ -13103,11 +13788,38 @@ ${lines.join("\n")}`;
13103
13788
  },
13104
13789
  // Extensional set. Elements do not repeat. The order of the elements is not significant.
13105
13790
  // For intensional set, use `Filter` with a condition, e.g. `Filter(RealNumbers, _ > 0)`
13791
+ //
13792
+ // A `Set` expression can also be a set-builder (comprehension), e.g.
13793
+ // `["Set", body, ["Element", k, domain, cond?]]` or
13794
+ // `["Set", body, ["Condition", ...]]` (see `parseSetComprehension()`).
13795
+ // Comprehensions are not literal 2-element sets: their elements are the
13796
+ // substituted bodies over the (filtered) domain.
13106
13797
  Set: {
13107
13798
  complexity: 8200,
13108
13799
  signature: "(any*) -> set",
13109
- type: (ops, { engine: _ce }) => parseType(`set<${BoxedType.widen(...ops.map((op) => op.type))}>`),
13800
+ type: (ops, { engine: _ce }) => {
13801
+ if (parseSetComprehension(ops) !== null) return parseType("set");
13802
+ return parseType(`set<${BoxedType.widen(...ops.map((op) => op.type))}>`);
13803
+ },
13110
13804
  canonical: canonicalSet,
13805
+ // The `lazy` flag suppresses the default operand evaluation: evaluating
13806
+ // the operands of a comprehension would mangle its indexing set (e.g.
13807
+ // the condition `gcd(n,k) = 1` with a free `k` evaluates to `False`).
13808
+ // Literal elements are evaluated explicitly in the `evaluate` handler.
13809
+ lazy: true,
13810
+ evaluate: (ops, { engine: ce, numericApproximation, materialization }) => {
13811
+ const comp = parseSetComprehension(ops);
13812
+ if (comp !== null) {
13813
+ const elements = enumerateSetComprehension(comp);
13814
+ if (elements === void 0 || elements.length > MAX_SIZE_EAGER_COLLECTION)
13815
+ return void 0;
13816
+ return ce.function("Set", elements);
13817
+ }
13818
+ return ce.function(
13819
+ "Set",
13820
+ ops.map((op) => op.evaluate({ numericApproximation, materialization }))
13821
+ );
13822
+ },
13111
13823
  eq: (a, b) => {
13112
13824
  if (a.operator !== b.operator) return false;
13113
13825
  if (!isFunction2(a) || !isFunction2(b)) return false;
@@ -13116,10 +13828,62 @@ ${lines.join("\n")}`;
13116
13828
  return a.ops.every(has);
13117
13829
  },
13118
13830
  collection: {
13119
- ...basicIndexedCollectionHandlers(),
13831
+ ...SET_BASE_HANDLERS,
13120
13832
  // A set is not indexable
13121
13833
  at: void 0,
13122
- indexWhere: void 0
13834
+ indexWhere: void 0,
13835
+ // A comprehension computes its elements on demand
13836
+ isLazy: (expr) => isFunction2(expr) && parseSetComprehension(expr.ops) !== null,
13837
+ count: (expr) => {
13838
+ if (!isFunction2(expr)) return 0;
13839
+ const comp = parseSetComprehension(expr.ops);
13840
+ if (comp === null) return expr.nops;
13841
+ return enumerateSetComprehension(comp)?.length;
13842
+ },
13843
+ isEmpty: (expr) => {
13844
+ if (!isFunction2(expr)) return true;
13845
+ const comp = parseSetComprehension(expr.ops);
13846
+ if (comp === null) return expr.nops === 0;
13847
+ const elements = enumerateSetComprehension(comp);
13848
+ return elements === void 0 ? void 0 : elements.length === 0;
13849
+ },
13850
+ isFinite: (expr) => {
13851
+ if (!isFunction2(expr)) return true;
13852
+ const comp = parseSetComprehension(expr.ops);
13853
+ if (comp === null) return true;
13854
+ if (enumerateSetComprehension(comp) !== void 0) return true;
13855
+ if (comp.domain?.isFiniteCollection === true) return true;
13856
+ return void 0;
13857
+ },
13858
+ iterator: (expr) => {
13859
+ if (!isFunction2(expr)) return SET_BASE_HANDLERS.iterator(expr);
13860
+ const comp = parseSetComprehension(expr.ops);
13861
+ if (comp === null) return SET_BASE_HANDLERS.iterator(expr);
13862
+ const elements = enumerateSetComprehension(comp);
13863
+ if (elements === void 0) return void 0;
13864
+ let i = 0;
13865
+ return {
13866
+ next: () => i >= elements.length ? { value: void 0, done: true } : { value: elements[i++], done: false }
13867
+ };
13868
+ },
13869
+ // Three-valued membership: `true` when an element matches, `false`
13870
+ // only when every element is definitively different from `target`
13871
+ // (concrete values), `undefined` otherwise — e.g. a symbolic target
13872
+ // (`Element(ω, {-1, 1})`) is indeterminate, not refuted.
13873
+ contains: (expr, target) => {
13874
+ if (!isFunction2(expr)) return void 0;
13875
+ const comp = parseSetComprehension(expr.ops);
13876
+ if (comp !== null) return setComprehensionContains(comp, target);
13877
+ return literalSetContains(expr.ops, target);
13878
+ },
13879
+ elttype: (expr) => {
13880
+ if (!isFunction2(expr)) return SET_BASE_HANDLERS.elttype(expr);
13881
+ const comp = parseSetComprehension(expr.ops);
13882
+ if (comp === null) return SET_BASE_HANDLERS.elttype(expr);
13883
+ const elements = enumerateSetComprehension(comp);
13884
+ if (elements === void 0 || elements.length === 0) return "unknown";
13885
+ return widen(...elements.map((op) => op.type.type));
13886
+ }
13123
13887
  }
13124
13888
  },
13125
13889
  Length: {
@@ -13219,7 +13983,12 @@ ${lines.join("\n")}`;
13219
13983
  },
13220
13984
  contains: (expr, target) => {
13221
13985
  const t = target.re;
13986
+ if (Number.isNaN(t))
13987
+ return typeMembership(target, "number") === false ? false : void 0;
13988
+ if (target.im !== 0) return false;
13222
13989
  if (!isFinite(t)) return false;
13990
+ if (isFunction2(expr) && expr.ops.some((op) => Number.isNaN(op.re)))
13991
+ return void 0;
13223
13992
  const [lower, upper, step] = range(expr);
13224
13993
  if (step === 0) return false;
13225
13994
  if (step > 0) {
@@ -13295,13 +14064,23 @@ ${lines.join("\n")}`;
13295
14064
  signature: "(number, number) -> set<real>",
13296
14065
  canonical: ([lo, hi], { engine }) => {
13297
14066
  if (!lo || !hi) return null;
14067
+ const unwrap2 = (op) => {
14068
+ if (isFunction2(op, "Open")) return [op.op1, true];
14069
+ if (isFunction2(op, "Closed")) return [op.op1, false];
14070
+ return [op, false];
14071
+ };
14072
+ const [loVal, loOpen] = unwrap2(lo);
14073
+ const [hiVal, hiOpen] = unwrap2(hi);
13298
14074
  const [lower, upper] = checkTypes(
13299
14075
  engine,
13300
- [lo.canonical, hi.canonical],
14076
+ [loVal.canonical, hiVal.canonical],
13301
14077
  ["number", "number"]
13302
14078
  );
13303
14079
  if (!lower.isValid || !upper.isValid) return null;
13304
- return engine._fn("Interval", [lower, upper]);
14080
+ return engine._fn("Interval", [
14081
+ loOpen ? engine._fn("Open", [lower]) : lower,
14082
+ hiOpen ? engine._fn("Open", [upper]) : upper
14083
+ ]);
13305
14084
  },
13306
14085
  eq: (a, b) => {
13307
14086
  const intervalA = interval(a);
@@ -13336,19 +14115,32 @@ ${lines.join("\n")}`;
13336
14115
  },
13337
14116
  isEmpty: (_expr) => {
13338
14117
  const int = interval(_expr);
13339
- if (!int) return false;
14118
+ if (!int) return void 0;
13340
14119
  if (int.openStart && int.start === int.end) return true;
13341
14120
  if (int.openEnd && int.start === int.end) return true;
13342
14121
  if (int.openStart && int.openEnd) return false;
13343
14122
  return int.start >= int.end;
13344
14123
  },
13345
14124
  isFinite: (_expr) => false,
14125
+ // Three-valued membership: `true` only when both bound checks are
14126
+ // entailed, `false` when a bound check (or the type of the target)
14127
+ // refutes membership, `undefined` otherwise (e.g. symbolic target
14128
+ // with unknown bounds). Endpoints may be ±Infinity.
13346
14129
  contains: (expr, target) => {
13347
14130
  const int = interval(expr);
13348
- if (!int) return false;
13349
- if (int.openStart && target.isLessEqual(int.start)) return false;
13350
- if (int.openEnd && target.isGreaterEqual(int.end)) return false;
13351
- return target.isGreaterEqual(int.start) && target.isLessEqual(int.end);
14131
+ if (!int) return void 0;
14132
+ if (typeMembership(target, "number") === false) return false;
14133
+ const t = target.re;
14134
+ if (!Number.isNaN(t)) {
14135
+ if (target.im !== 0) return false;
14136
+ return intervalContains(int, t);
14137
+ }
14138
+ const aboveLower = int.openStart ? target.isGreater(int.start) : target.isGreaterEqual(int.start);
14139
+ if (aboveLower === false) return false;
14140
+ const belowUpper = int.openEnd ? target.isLess(int.end) : target.isLessEqual(int.end);
14141
+ if (belowUpper === false) return false;
14142
+ if (aboveLower === true && belowUpper === true) return true;
14143
+ return void 0;
13352
14144
  },
13353
14145
  eltsgn: (expr) => {
13354
14146
  const i = interval(expr);
@@ -13430,11 +14222,15 @@ ${lines.join("\n")}`;
13430
14222
  };
13431
14223
  },
13432
14224
  contains: (expr, target) => {
13433
- if (!target.type.matches("finite_real")) return false;
13434
- if (!isFunction2(expr)) return false;
13435
14225
  const t = target.re;
14226
+ if (Number.isNaN(t))
14227
+ return typeMembership(target, "number") === false ? false : void 0;
14228
+ if (target.im !== 0) return false;
14229
+ if (!isFinite(t)) return false;
14230
+ if (!isFunction2(expr)) return void 0;
13436
14231
  const lower = expr.op1.re;
13437
14232
  const upper = expr.op2.re;
14233
+ if (Number.isNaN(lower) || Number.isNaN(upper)) return void 0;
13438
14234
  if (t < lower || t > upper) return false;
13439
14235
  let count = expr.op3.re;
13440
14236
  if (!isFinite(count)) count = DEFAULT_LINSPACE_COUNT;
@@ -13464,8 +14260,18 @@ ${lines.join("\n")}`;
13464
14260
  description: ["Return the number of elements in the collection."],
13465
14261
  complexity: 8200,
13466
14262
  signature: "(collection) -> integer",
13467
- evaluate: ([xs], { engine }) => xs.isEmptyCollection ? engine.Zero : engine.number(xs.count),
13468
- sgn: ([xs]) => xs.isEmptyCollection ? "zero" : "positive"
14263
+ evaluate: ([xs], { engine }) => {
14264
+ if (xs.isEmptyCollection) return engine.Zero;
14265
+ const n = xs.count;
14266
+ if (n === void 0) return void 0;
14267
+ return engine.number(n);
14268
+ },
14269
+ sgn: ([xs]) => {
14270
+ const empty = xs.isEmptyCollection;
14271
+ if (empty === true) return "zero";
14272
+ if (empty === false) return "positive";
14273
+ return void 0;
14274
+ }
13469
14275
  },
13470
14276
  IsEmpty: {
13471
14277
  description: ["Return True if the collection is empty, False otherwise."],
@@ -13581,7 +14387,13 @@ ${lines.join("\n")}`;
13581
14387
  },
13582
14388
  collection: {
13583
14389
  isLazy: (_expr) => true,
13584
- count: (_expr) => Infinity,
14390
+ count: (expr) => {
14391
+ if (!isFunction2(expr)) return void 0;
14392
+ if (!expr.op1.isFiniteCollection) return Infinity;
14393
+ let n = 0;
14394
+ for (const _ of expr.each()) n++;
14395
+ return n;
14396
+ },
13585
14397
  contains: (expr, target) => {
13586
14398
  if (!isFunction2(expr)) return false;
13587
14399
  if (!expr.contains(target)) return false;
@@ -13690,24 +14502,26 @@ ${lines.join("\n")}`;
13690
14502
  type: (ops) => parseType(functionResult(ops[1].type.type) ?? "unknown"),
13691
14503
  evaluate: ([collection, fn, initial], { engine: ce }) => {
13692
14504
  if (!collection.isFiniteCollection) return void 0;
14505
+ const hasInitial = initial !== void 0;
13693
14506
  initial ??= ce.Nothing;
13694
14507
  if (initial.type.matches("real") && collection.type.matches(ce.type("collection<real>"))) {
13695
14508
  const compiled = ce._compile(fn);
13696
- if (compiled.calling !== "lambda" || !compiled.run) return void 0;
13697
- return run(
13698
- (function* () {
13699
- let accumulator = initial.re;
13700
- let first = true;
13701
- for (const item of collection.each()) {
13702
- if (first) accumulator = item.re;
13703
- else accumulator = compiled.run(accumulator, item.re);
13704
- first = false;
13705
- yield;
13706
- }
13707
- return ce.expr(accumulator);
13708
- })(),
13709
- ce._timeRemaining
13710
- );
14509
+ if (compiled.calling === "lambda" && compiled.run) {
14510
+ return run(
14511
+ (function* () {
14512
+ let accumulator = hasInitial ? initial.re : NaN;
14513
+ let first = true;
14514
+ for (const item of collection.each()) {
14515
+ if (first && !hasInitial) accumulator = item.re;
14516
+ else accumulator = compiled.run(accumulator, item.re);
14517
+ first = false;
14518
+ yield;
14519
+ }
14520
+ return ce.expr(accumulator);
14521
+ })(),
14522
+ ce._timeRemaining
14523
+ );
14524
+ }
13711
14525
  }
13712
14526
  const f = applicable(fn);
13713
14527
  return run(
@@ -13900,10 +14714,13 @@ ${lines.join("\n")}`;
13900
14714
  const [xs, nExpr] = expr.ops;
13901
14715
  const n = toInteger(nExpr) ?? 0;
13902
14716
  if (n <= 0) return xs.each();
14717
+ const count = xs.count;
13903
14718
  let index = n + 1;
13904
14719
  return {
13905
14720
  next: () => {
13906
- const value = expr.op1.at(index++);
14721
+ if (count !== void 0 && index > count)
14722
+ return { value: void 0, done: true };
14723
+ const value = xs.at(index++);
13907
14724
  if (value === void 0) return { value: void 0, done: true };
13908
14725
  return { value, done: false };
13909
14726
  }
@@ -13914,7 +14731,13 @@ ${lines.join("\n")}`;
13914
14731
  if (!isFunction2(expr)) return void 0;
13915
14732
  const [xs, nExpr] = expr.ops;
13916
14733
  const n = toInteger(nExpr) ?? 0;
13917
- if (n <= 0) return void 0;
14734
+ if (n <= 0) return xs.at(index);
14735
+ if (index < 0) {
14736
+ const count = xs.count;
14737
+ if (count !== void 0 && -index > count - n) return void 0;
14738
+ return xs.at(index);
14739
+ }
14740
+ if (index < 1) return void 0;
13918
14741
  return xs.at(index + n);
13919
14742
  }
13920
14743
  }
@@ -13996,11 +14819,15 @@ ${lines.join("\n")}`;
13996
14819
  iterator: (expr) => {
13997
14820
  if (!isFunction2(expr))
13998
14821
  return { next: () => ({ value: void 0, done: true }) };
14822
+ const op1 = expr.op1;
14823
+ const count = op1.count;
14824
+ let index = 2;
13999
14825
  return {
14000
14826
  next: () => {
14001
- let index = 1;
14002
- const value = expr.op1.at(index > 0 ? index + 1 : index);
14003
- if (!value) return { value: void 0, done: true };
14827
+ if (count !== void 0 && index > count)
14828
+ return { value: void 0, done: true };
14829
+ const value = op1.at(index);
14830
+ if (value === void 0) return { value: void 0, done: true };
14004
14831
  index += 1;
14005
14832
  return { value, done: false };
14006
14833
  }
@@ -14079,12 +14906,17 @@ ${lines.join("\n")}`;
14079
14906
  isLazy: (_expr) => true,
14080
14907
  count: (expr) => {
14081
14908
  if (!isFunction2(expr)) return void 0;
14082
- const start = toInteger(expr.op2) ?? 1;
14083
14909
  const count = expr.op1.count;
14084
14910
  if (count === void 0) return void 0;
14085
- const end = toInteger(expr.op3) ?? count;
14086
- if (start < 1) return Math.max(0, end + start - 1);
14087
- return Math.max(0, Math.min(end, count) - start + 1);
14911
+ let start = toInteger(expr.op2) ?? 1;
14912
+ if (start < 1) start = count + 1 + start;
14913
+ if (start < 1) start = 1;
14914
+ if (start > count) return 0;
14915
+ let end = toInteger(expr.op3) ?? count;
14916
+ if (end < 1) end = count + 1 + end;
14917
+ if (end < 1) end = 1;
14918
+ if (end > count) end = count;
14919
+ return Math.max(0, end - start + 1);
14088
14920
  },
14089
14921
  isFinite: (_expr) => true,
14090
14922
  at: (expr, index) => {
@@ -14100,6 +14932,11 @@ ${lines.join("\n")}`;
14100
14932
  if (end < 1) end = count + 1 + end;
14101
14933
  if (end < 1) end = 1;
14102
14934
  if (end > count) end = count;
14935
+ const length = end - start + 1;
14936
+ if (length <= 0) return void 0;
14937
+ if (index < 0) index = length + 1 + index;
14938
+ if (index < 1 || index > length) return void 0;
14939
+ return expr.op1.at(start + index - 1);
14103
14940
  },
14104
14941
  iterator: (expr) => {
14105
14942
  if (!isFunction2(expr))
@@ -14363,7 +15200,7 @@ ${lines.join("\n")}`;
14363
15200
  for (const item of xs.each()) {
14364
15201
  const pred = sym(f([item]));
14365
15202
  if (pred === "True") indices.push(ce.number(index));
14366
- if (pred !== "False")
15203
+ else if (pred !== "False")
14367
15204
  throw new Error(
14368
15205
  `Filter predicate must return "True" or "False". ${spellCheckMessage(
14369
15206
  fn
@@ -14612,11 +15449,25 @@ ${lines.join("\n")}`;
14612
15449
  count: zipCount,
14613
15450
  isFinite: (expr) => {
14614
15451
  if (!isFunction2(expr)) return void 0;
14615
- return expr.ops.every((x) => x.isFiniteCollection);
15452
+ if (expr.nops === 0) return true;
15453
+ let anyUnknown = false;
15454
+ for (const x of expr.ops) {
15455
+ const f = x.isFiniteCollection;
15456
+ if (f === true) return true;
15457
+ if (f === void 0) anyUnknown = true;
15458
+ }
15459
+ return anyUnknown ? void 0 : false;
14616
15460
  },
14617
15461
  isEmpty: (expr) => {
14618
15462
  if (!isFunction2(expr)) return void 0;
14619
- return expr.nops === 0 || expr.ops.every((x) => x.isEmptyCollection);
15463
+ if (expr.nops === 0) return true;
15464
+ let anyUnknown = false;
15465
+ for (const x of expr.ops) {
15466
+ const e = x.isEmptyCollection;
15467
+ if (e === true) return true;
15468
+ if (e === void 0) anyUnknown = true;
15469
+ }
15470
+ return anyUnknown ? void 0 : false;
14620
15471
  },
14621
15472
  iterator: (expr) => {
14622
15473
  if (!isFunction2(expr))
@@ -14776,9 +15627,22 @@ ${lines.join("\n")}`;
14776
15627
  signature: "(list) -> list",
14777
15628
  collection: {
14778
15629
  isLazy: (_expr) => true,
14779
- count: () => Infinity,
14780
- isEmpty: (expr) => expr.isEmptyCollection,
14781
- isFinite: (expr) => !expr.isEmptyCollection,
15630
+ // Cycling a non-empty collection is infinite; cycling an empty one is
15631
+ // empty. Inspect the *underlying* collection (`op1`) reading
15632
+ // `expr.isEmptyCollection`/`expr.isFiniteCollection` here would re-enter
15633
+ // these same handlers and recurse infinitely.
15634
+ count: (expr) => {
15635
+ if (!isFunction2(expr)) return void 0;
15636
+ return expr.op1.isEmptyCollection ? 0 : Infinity;
15637
+ },
15638
+ isEmpty: (expr) => {
15639
+ if (!isFunction2(expr)) return void 0;
15640
+ return expr.op1.isEmptyCollection;
15641
+ },
15642
+ isFinite: (expr) => {
15643
+ if (!isFunction2(expr)) return void 0;
15644
+ return expr.op1.isEmptyCollection;
15645
+ },
14782
15646
  contains: (expr, target) => {
14783
15647
  if (!isFunction2(expr)) return false;
14784
15648
  return expr.op1.contains(target) ?? false;
@@ -14792,7 +15656,7 @@ ${lines.join("\n")}`;
14792
15656
  return { next: () => ({ value: void 0, done: true }) };
14793
15657
  return {
14794
15658
  next: () => {
14795
- const i = (index - 1 - 1) % l + 1;
15659
+ const i = (index - 1) % l + 1;
14796
15660
  const value = expr.op1.at(i);
14797
15661
  if (value === void 0) return { value: void 0, done: true };
14798
15662
  index += 1;
@@ -14914,7 +15778,7 @@ ${lines.join("\n")}`;
14914
15778
  evaluate: (ops, { engine: ce }) => {
14915
15779
  const elements = [];
14916
15780
  for (const xs of ops) {
14917
- if (xs.isCollection) elements.push(xs);
15781
+ if (!xs.isCollection) elements.push(xs);
14918
15782
  else {
14919
15783
  if (!xs.isFiniteCollection) return void 0;
14920
15784
  elements.push(...Array.from(xs.each()));
@@ -14930,7 +15794,7 @@ ${lines.join("\n")}`;
14930
15794
  evaluate: (ops, { engine: ce }) => {
14931
15795
  const elements = [];
14932
15796
  for (const xs of ops) {
14933
- if (xs.isCollection) elements.push(xs);
15797
+ if (!xs.isCollection) elements.push(xs);
14934
15798
  else {
14935
15799
  if (!xs.isFiniteCollection) return void 0;
14936
15800
  elements.push(...Array.from(xs.each()));
@@ -15023,11 +15887,129 @@ ${lines.join("\n")}`;
15023
15887
  return ce._fn("List", ops);
15024
15888
  }
15025
15889
  function canonicalSet(ops, { engine }) {
15890
+ ops = ops.map((op) => op.canonical);
15891
+ if (parseSetComprehension(ops) !== null) return engine._fn("Set", [...ops]);
15026
15892
  const set = [];
15027
15893
  const has = (x) => set.some((y) => y.isSame(x));
15028
15894
  for (const op of ops) if (!has(op)) set.push(op);
15029
15895
  return engine._fn("Set", set);
15030
15896
  }
15897
+ function parseSetComprehension(ops) {
15898
+ if (ops.length !== 2) return null;
15899
+ const [body, spec] = ops;
15900
+ const canon = (x) => x.isCanonical ? x : x.canonical;
15901
+ if (isFunction2(spec, "Element") && spec.nops >= 2) {
15902
+ if (!isSymbol2(spec.op1)) return null;
15903
+ const v = spec.op1.symbol;
15904
+ if (!body.has(v)) return null;
15905
+ const cond = spec.nops >= 3 && sym(spec.op3) !== "Nothing" ? spec.op3 : void 0;
15906
+ return { body, variable: v, domain: spec.op2, condition: cond };
15907
+ }
15908
+ if (isFunction2(spec, "Condition") && spec.nops >= 1) {
15909
+ const pred = spec.op1;
15910
+ if (isFunction2(body, "Element") && body.nops === 2 && isSymbol2(body.op1)) {
15911
+ return {
15912
+ body: body.op1,
15913
+ variable: body.op1.symbol,
15914
+ domain: canon(body.op2),
15915
+ condition: canon(pred)
15916
+ };
15917
+ }
15918
+ if (isFunction2(pred, "Element") && pred.nops === 2 && isSymbol2(pred.op1)) {
15919
+ const v = pred.op1.symbol;
15920
+ if (body.has(v))
15921
+ return {
15922
+ body,
15923
+ variable: v,
15924
+ domain: canon(pred.op2),
15925
+ condition: void 0
15926
+ };
15927
+ }
15928
+ if (isFunction2(pred, "And")) {
15929
+ const memberships = pred.ops.filter(
15930
+ (x) => isFunction2(x, "Element") && x.nops === 2 && isSymbol2(x.op1) && body.has(x.op1.symbol)
15931
+ );
15932
+ const membership = memberships.length === 1 ? memberships[0] : void 0;
15933
+ if (membership && isFunction2(membership, "Element") && isSymbol2(membership.op1)) {
15934
+ const rest = pred.ops.filter((x) => x !== membership).map(canon);
15935
+ const ce = body.engine;
15936
+ const cond = rest.length === 0 ? void 0 : rest.length === 1 ? rest[0] : ce._fn("And", rest);
15937
+ return {
15938
+ body,
15939
+ variable: membership.op1.symbol,
15940
+ domain: canon(membership.op2),
15941
+ condition: cond
15942
+ };
15943
+ }
15944
+ }
15945
+ return {
15946
+ body,
15947
+ variable: isSymbol2(body) ? body.symbol : void 0,
15948
+ domain: void 0,
15949
+ condition: pred
15950
+ };
15951
+ }
15952
+ return null;
15953
+ }
15954
+ function enumerateSetComprehension(comp) {
15955
+ const { body, variable, domain, condition } = comp;
15956
+ if (variable === void 0 || domain === void 0) return void 0;
15957
+ const ce = body.engine;
15958
+ const extract = (dom) => extractFiniteDomainWithReason(
15959
+ ce._fn("Element", [
15960
+ ce.symbol(variable),
15961
+ dom,
15962
+ ...condition ? [condition] : []
15963
+ ]),
15964
+ ce
15965
+ );
15966
+ let result = extract(domain);
15967
+ if (result.status !== "success") {
15968
+ const evaluatedDomain = domain.evaluate();
15969
+ if (!evaluatedDomain.isSame(domain)) result = extract(evaluatedDomain);
15970
+ }
15971
+ if (result.status !== "success") return void 0;
15972
+ const isIdentity = isSymbol2(body) && body.symbol === variable;
15973
+ const elements = [];
15974
+ for (const value of result.values) {
15975
+ const x = isIdentity ? value : body.subs({ [variable]: value }).evaluate();
15976
+ if (!elements.some((y) => y.isSame(x))) elements.push(x);
15977
+ }
15978
+ return elements;
15979
+ }
15980
+ function literalSetContains(ops, target) {
15981
+ let indeterminate = false;
15982
+ for (const op of ops) {
15983
+ if (target.isSame(op)) return true;
15984
+ if (isNumber(target) && isNumber(op)) {
15985
+ const eq2 = target.isEqual(op);
15986
+ if (eq2 === true) return true;
15987
+ if (eq2 !== false) indeterminate = true;
15988
+ } else if (isString(target) && isString(op)) {
15989
+ } else {
15990
+ indeterminate = true;
15991
+ }
15992
+ }
15993
+ return indeterminate ? void 0 : false;
15994
+ }
15995
+ function setComprehensionContains(comp, target) {
15996
+ const elements = enumerateSetComprehension(comp);
15997
+ if (elements !== void 0) return literalSetContains(elements, target);
15998
+ if (comp.domain !== void 0 && comp.variable !== void 0 && isSymbol2(comp.body) && comp.body.symbol === comp.variable) {
15999
+ const inDomain = comp.domain.contains(target);
16000
+ if (inDomain === false) return false;
16001
+ let condition = true;
16002
+ if (comp.condition !== void 0) {
16003
+ if (isNumber(target) || isString(target)) {
16004
+ const result = comp.condition.subs({ [comp.variable]: target }).evaluate();
16005
+ condition = sym(result) === "True" ? true : sym(result) === "False" ? false : void 0;
16006
+ } else condition = void 0;
16007
+ }
16008
+ if (condition === false) return false;
16009
+ if (inDomain === true && condition === true) return true;
16010
+ }
16011
+ return void 0;
16012
+ }
15031
16013
  function tally(collection) {
15032
16014
  const values = [];
15033
16015
  const counts = [];
@@ -15267,7 +16249,11 @@ ${lines.join("\n")}`;
15267
16249
  op[1]
15268
16250
  )}`;
15269
16251
  } else {
15270
- resultStr = args.map((arg) => _BaseCompiler.compile(arg, target, op[1])).join(` ${op[0]} `);
16252
+ const rightAssoc = h === "Power";
16253
+ resultStr = args.map((arg, i) => {
16254
+ const operandPrec = rightAssoc && i < args.length - 1 ? op[1] + 1 : op[1];
16255
+ return _BaseCompiler.compile(arg, target, operandPrec);
16256
+ }).join(` ${op[0]} `);
15271
16257
  }
15272
16258
  return op[1] < prec ? `(${resultStr})` : resultStr;
15273
16259
  }
@@ -15960,6 +16946,17 @@ ${lines.join("\n")}`;
15960
16946
  `Compilation fallback for "${expr.operator}" (target: ${options?.to ?? "javascript"}): ${e.message}`
15961
16947
  );
15962
16948
  const ce = expr.engine;
16949
+ const target = options?.to ?? "javascript";
16950
+ if (isFunction2(expr, "Function")) {
16951
+ const lambdaRun = ((...args) => ce.function("Apply", [expr, ...args.map((a) => ce.box(a))]).evaluate().re);
16952
+ return {
16953
+ target,
16954
+ success: false,
16955
+ code: "",
16956
+ calling: "lambda",
16957
+ run: lambdaRun
16958
+ };
16959
+ }
15963
16960
  const fallbackRun = ((vars) => {
15964
16961
  ce.pushScope();
15965
16962
  try {
@@ -15972,7 +16969,7 @@ ${lines.join("\n")}`;
15972
16969
  }
15973
16970
  });
15974
16971
  return {
15975
- target: options?.to ?? "javascript",
16972
+ target,
15976
16973
  success: false,
15977
16974
  code: "",
15978
16975
  calling: "expression",
@@ -16026,6 +17023,11 @@ ${lines.join("\n")}`;
16026
17023
  if (symbolic.length === 1) return symbolic[0];
16027
17024
  return symbolic.join(op === "+" ? " + " : " * ");
16028
17025
  }
17026
+ function parenthesizeFactor(expr, code) {
17027
+ if (isFunction2(expr, "Add") || isFunction2(expr, "Subtract"))
17028
+ return `(${code})`;
17029
+ return code;
17030
+ }
16029
17031
  function tryGetComplexParts(expr, compile2) {
16030
17032
  if (isSymbol2(expr, "ImaginaryUnit")) {
16031
17033
  return { re: null, im: "1.0" };
@@ -16050,7 +17052,9 @@ ${lines.join("\n")}`;
16050
17052
  if (remaining.length === 0) {
16051
17053
  return { re: null, im: formatFloat(iScale) };
16052
17054
  }
16053
- const compiledFactors = remaining.map((r) => compile2(r));
17055
+ const compiledFactors = remaining.map(
17056
+ (r) => parenthesizeFactor(r, compile2(r))
17057
+ );
16054
17058
  if (iScale !== 1) compiledFactors.unshift(formatFloat(iScale));
16055
17059
  const imCode = foldTerms(compiledFactors, "1.0", "*");
16056
17060
  return { re: null, im: imCode };
@@ -19567,9 +20571,14 @@ ${lines.join("\n")}`;
19567
20571
  ];
19568
20572
  function gammaln(z) {
19569
20573
  if (z < 0) return NaN;
20574
+ let shift = 0;
20575
+ while (z < 10) {
20576
+ shift += Math.log(z);
20577
+ z += 1;
20578
+ }
19570
20579
  const pi = Math.PI;
19571
20580
  const z3 = z * z * z;
19572
- 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);
20581
+ 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;
19573
20582
  }
19574
20583
  function gamma(z) {
19575
20584
  if (z < 0.5) return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
@@ -19580,31 +20589,62 @@ ${lines.join("\n")}`;
19580
20589
  const t = z + gammaG + 0.5;
19581
20590
  return Math.sqrt(2 * Math.PI) * Math.pow(t, z + 0.5) * Math.exp(-t) * x;
19582
20591
  }
20592
+ function erfInvApprox(x) {
20593
+ const a = 0.147;
20594
+ const ln1mx2 = Math.log(1 - x * x);
20595
+ const b = 2 / (Math.PI * a) + ln1mx2 / 2;
20596
+ return Math.sign(x) * Math.sqrt(Math.sqrt(b * b - ln1mx2 / a) - b);
20597
+ }
19583
20598
  function erfInv(x) {
19584
- const pi = Math.PI;
19585
- const pi2 = pi * pi;
19586
- const pi3 = pi2 * pi;
19587
- const x2 = x * x;
19588
- const x3 = x * x2;
19589
- const x5 = x3 * x2;
19590
- const x7 = x5 * x2;
19591
- 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);
20599
+ if (Number.isNaN(x) || x < -1 || x > 1) return NaN;
20600
+ if (x === 0) return 0;
20601
+ if (x === 1) return Infinity;
20602
+ if (x === -1) return -Infinity;
20603
+ const sign2 = x < 0 ? -1 : 1;
20604
+ const ax = Math.abs(x);
20605
+ let y = erfInvApprox(ax);
20606
+ const c = Math.sqrt(Math.PI) / 2;
20607
+ for (let i = 0; i < 4; i++) y -= (erf(y) - ax) * c * Math.exp(y * y);
20608
+ return sign2 * y;
19592
20609
  }
19593
20610
  function erfc(x) {
19594
- return 1 - erf(x);
20611
+ if (Number.isNaN(x)) return NaN;
20612
+ if (!Number.isFinite(x)) return x > 0 ? 0 : 2;
20613
+ if (x < 0) return 2 - erfc(-x);
20614
+ if (x < 2) return 1 - erf(x);
20615
+ const tiny = 1e-300;
20616
+ let f = x === 0 ? tiny : x;
20617
+ let c = f;
20618
+ let d = 0;
20619
+ for (let k = 1; k <= 500; k++) {
20620
+ const a = k / 2;
20621
+ d = x + a * d;
20622
+ if (d === 0) d = tiny;
20623
+ d = 1 / d;
20624
+ c = x + a / c;
20625
+ if (c === 0) c = tiny;
20626
+ const delta = c * d;
20627
+ f *= delta;
20628
+ if (Math.abs(delta - 1) < 1e-17) break;
20629
+ }
20630
+ return Math.exp(-x * x) / (Math.sqrt(Math.PI) * f);
19595
20631
  }
19596
20632
  function erf(x) {
19597
- const a1 = 0.254829592;
19598
- const a2 = -0.284496736;
19599
- const a3 = 1.421413741;
19600
- const a4 = -1.453152027;
19601
- const a5 = 1.061405429;
19602
- const p = 0.3275911;
20633
+ if (Number.isNaN(x)) return NaN;
20634
+ if (x === 0) return 0;
20635
+ if (!Number.isFinite(x)) return x > 0 ? 1 : -1;
19603
20636
  const sign2 = x < 0 ? -1 : 1;
19604
- x = Math.abs(x);
19605
- const t = 1 / (1 + p * x);
19606
- const y = ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t;
19607
- return sign2 * (1 - y * Math.exp(-x * x));
20637
+ const ax = Math.abs(x);
20638
+ if (ax >= 6) return sign2;
20639
+ const x2 = ax * ax;
20640
+ let term = ax;
20641
+ let sum = ax;
20642
+ for (let n = 1; n < 200; n++) {
20643
+ term *= 2 * x2 / (2 * n + 1);
20644
+ sum += term;
20645
+ if (term < sum * 1e-18) break;
20646
+ }
20647
+ return sign2 * (2 / Math.sqrt(Math.PI)) * Math.exp(-x2) * sum;
19608
20648
  }
19609
20649
  var EULER_MASCHERONI = 0.5772156649015329;
19610
20650
  var BERNOULLI_2K = [
@@ -20190,7 +21230,7 @@ ${lines.join("\n")}`;
20190
21230
  const t = x2 * x2;
20191
21231
  return sign2 * x * x2 * polevl(t, SN) / polevl(t, SD);
20192
21232
  }
20193
- if (x < 36) {
21233
+ if (x < 36974) {
20194
21234
  const x2 = x * x;
20195
21235
  const t = Math.PI * x2;
20196
21236
  const u = 1 / (t * t);
@@ -20215,7 +21255,7 @@ ${lines.join("\n")}`;
20215
21255
  const t = x2 * x2;
20216
21256
  return sign2 * x * polevl(t, CN) / polevl(t, CD);
20217
21257
  }
20218
- if (x < 36) {
21258
+ if (x < 36974) {
20219
21259
  const x2 = x * x;
20220
21260
  const t = Math.PI * x2;
20221
21261
  const u = 1 / (t * t);
@@ -20306,6 +21346,7 @@ ${lines.join("\n")}`;
20306
21346
  function kurtosis(values) {
20307
21347
  let sum = 0;
20308
21348
  let sum2 = 0;
21349
+ let sum3 = 0;
20309
21350
  let sum4 = 0;
20310
21351
  let count = 0;
20311
21352
  for (const op of values) {
@@ -20313,12 +21354,16 @@ ${lines.join("\n")}`;
20313
21354
  if (!Number.isFinite(v)) return NaN;
20314
21355
  sum += v;
20315
21356
  sum2 += v * v;
21357
+ sum3 += v * v * v;
20316
21358
  sum4 += v * v * v * v;
20317
21359
  count++;
20318
21360
  }
20319
21361
  if (count === 0) return NaN;
20320
- const s2 = (sum2 - sum * sum / count) / (count - 1);
20321
- return (sum4 - 4 * sum * sum2 / count + 6 * sum * sum * sum / count / count - 3 * sum * sum * sum * sum / count / count / count) / (s2 * s2);
21362
+ const n = count;
21363
+ const m = sum / n;
21364
+ const m2 = (sum2 - sum * sum / n) / n;
21365
+ const m4 = (sum4 - 4 * m * sum3 + 6 * m * m * sum2 - 4 * m * m * m * sum + n * m * m * m * m) / n;
21366
+ return m4 / (m2 * m2);
20322
21367
  }
20323
21368
  function skewness(values) {
20324
21369
  let sum = 0;
@@ -20334,9 +21379,11 @@ ${lines.join("\n")}`;
20334
21379
  count++;
20335
21380
  }
20336
21381
  if (count === 0) return NaN;
20337
- const s2 = (sum2 - sum * sum / count) / (count - 1);
20338
- const s3 = (sum3 - sum2 * sum / count) / (count - 1);
20339
- return s3 / Math.pow(s2, 3 / 2) * Math.sqrt(count * 1);
21382
+ const n = count;
21383
+ const m = sum / n;
21384
+ const m2 = (sum2 - sum * sum / n) / n;
21385
+ const m3 = (sum3 - 3 * m * sum2 + 3 * m * m * sum - n * m * m * m) / n;
21386
+ return m3 / Math.pow(m2, 3 / 2);
20340
21387
  }
20341
21388
  function mode(values) {
20342
21389
  const counts = {};
@@ -20363,11 +21410,8 @@ ${lines.join("\n")}`;
20363
21410
  return [q1, q2, q3];
20364
21411
  }
20365
21412
  function interquartileRange(values) {
20366
- const sorted = [...values].sort((a, b) => a - b);
20367
- const mid = Math.floor(sorted.length / 2);
20368
- const lower = sorted.slice(0, mid);
20369
- const upper = sorted.slice(mid + 1);
20370
- return median(upper) - median(lower);
21413
+ const [q1, , q3] = quartiles(values);
21414
+ return q3 - q1;
20371
21415
  }
20372
21416
 
20373
21417
  // src/compute-engine/numerics/monte-carlo.ts
@@ -20698,7 +21742,7 @@ ${lines.join("\n")}`;
20698
21742
  if (parseFloat(step) === 1) {
20699
21743
  const fStop = parseFloat(stop);
20700
21744
  const fStart = parseFloat(start);
20701
- if (fStop !== null && fStart !== null) {
21745
+ if (!isNaN(fStop) && !isNaN(fStart)) {
20702
21746
  if (fStop - fStart < 50) {
20703
21747
  return `[${Array.from(
20704
21748
  { length: fStop - fStart + 1 },
@@ -20709,9 +21753,9 @@ ${lines.join("\n")}`;
20709
21753
  }, (_, i) => ${start} + i)`;
20710
21754
  }
20711
21755
  return `Array.from({length: ${stop} - ${start} + 1
20712
- }, (_, i) => ${start} + i)`;
21756
+ }, (_e, i) => ${start} + i)`;
20713
21757
  }
20714
- return `Array.from({length: Math.floor((${stop} - ${start}) / ${step}) + 1}, (_, i) => ${start} + i * ${step})`;
21758
+ return `Array.from({length: Math.floor((${stop} - ${start}) / ${step}) + 1}, (_e, i) => ${start} + i * ${step})`;
20715
21759
  },
20716
21760
  Root: ([arg, exp3], compile2) => {
20717
21761
  if (arg === null) throw new Error("Root: no argument");
@@ -21868,6 +22912,14 @@ ${lines.join("\n")}`;
21868
22912
  function gpuVec3(target) {
21869
22913
  return target?.language === "wgsl" ? "vec3f" : "vec3";
21870
22914
  }
22915
+ function gpuNaN(target) {
22916
+ return target?.language === "wgsl" ? "bitcast<f32>(0x7fc00000u)" : "(0.0 / 0.0)";
22917
+ }
22918
+ function gpuConditional(cond, whenTrue, whenFalse, target) {
22919
+ if (target?.language === "wgsl")
22920
+ return `select(${whenFalse}, ${whenTrue}, ${cond})`;
22921
+ return `((${cond}) ? (${whenTrue}) : (${whenFalse}))`;
22922
+ }
21871
22923
  function readStringLiteral(expr) {
21872
22924
  if (!isString(expr)) return null;
21873
22925
  return expr.string?.toLowerCase() ?? null;
@@ -21985,7 +23037,7 @@ ${lines.join("\n")}`;
21985
23037
  const realFactors = args.filter((_, i) => i !== iIndex);
21986
23038
  const v2 = gpuVec2(target);
21987
23039
  if (realFactors.length === 0) return `${v2}(0.0, ${formatFloat(iScale)})`;
21988
- const factors = realFactors.map((f) => compile2(f));
23040
+ const factors = realFactors.map((f) => parenthesizeFactor(f, compile2(f)));
21989
23041
  if (iScale !== 1) factors.unshift(formatFloat(iScale));
21990
23042
  const imCode = foldTerms(factors, "1.0", "*");
21991
23043
  return `${v2}(0.0, ${imCode})`;
@@ -21994,7 +23046,7 @@ ${lines.join("\n")}`;
21994
23046
  const complexCodes = [];
21995
23047
  for (const a of args) {
21996
23048
  if (BaseCompiler.isComplexValued(a)) complexCodes.push(compile2(a));
21997
- else realCodes.push(compile2(a));
23049
+ else realCodes.push(parenthesizeFactor(a, compile2(a)));
21998
23050
  }
21999
23051
  const scalarCode = foldTerms(realCodes, "1.0", "*");
22000
23052
  let result = complexCodes[0];
@@ -22072,7 +23124,9 @@ ${lines.join("\n")}`;
22072
23124
  return `_gpu_ccos(${compile2(args[0])})`;
22073
23125
  return `cos(${compile2(args[0])})`;
22074
23126
  },
22075
- Degrees: "degrees",
23127
+ // CE's `Degrees` converts degrees→radians (Degrees(180) = π), which is
23128
+ // GLSL's `radians()`. GLSL's `degrees()` is the inverse (rad→deg).
23129
+ Degrees: "radians",
22076
23130
  Exp: (args, compile2) => {
22077
23131
  if (BaseCompiler.isComplexValued(args[0]))
22078
23132
  return `_gpu_cexp(${compile2(args[0])})`;
@@ -22101,6 +23155,43 @@ ${lines.join("\n")}`;
22101
23155
  Max: "max",
22102
23156
  Min: "min",
22103
23157
  Mix: "mix",
23158
+ // Control-flow forms — the base compiler's default emits a JS ternary and a
23159
+ // bare `NaN`, neither of which is valid GPU code (WGSL has no `?:`, and no
23160
+ // shader language has a `NaN` identifier). Emit `select(...)` for WGSL and a
23161
+ // language-appropriate NaN.
23162
+ If: (args, compile2, target) => {
23163
+ if (args.length !== 3) throw new Error("If: wrong number of arguments");
23164
+ return gpuConditional(
23165
+ compile2(args[0]),
23166
+ compile2(args[1]),
23167
+ compile2(args[2]),
23168
+ target
23169
+ );
23170
+ },
23171
+ When: (args, compile2, target) => {
23172
+ if (args.length !== 2)
23173
+ throw new Error("When: expected exactly 2 arguments (expr, cond)");
23174
+ if (isSymbol2(args[1], "True")) return `(${compile2(args[0])})`;
23175
+ if (isSymbol2(args[1], "False")) return gpuNaN(target);
23176
+ return gpuConditional(
23177
+ compile2(args[1]),
23178
+ compile2(args[0]),
23179
+ gpuNaN(target),
23180
+ target
23181
+ );
23182
+ },
23183
+ Which: (args, compile2, target) => {
23184
+ if (args.length < 2 || args.length % 2 !== 0)
23185
+ throw new Error("Which: expected condition/value pairs");
23186
+ const build = (i) => {
23187
+ if (i >= args.length) return gpuNaN(target);
23188
+ const cond = args[i];
23189
+ const val = args[i + 1];
23190
+ if (isSymbol2(cond, "True")) return `(${compile2(val)})`;
23191
+ return gpuConditional(compile2(cond), compile2(val), build(i + 2), target);
23192
+ };
23193
+ return build(0);
23194
+ },
22104
23195
  Power: (args, compile2, target) => {
22105
23196
  const base = args[0];
22106
23197
  const exp3 = args[1];
@@ -22788,7 +23879,7 @@ ${lines.join("\n")}`;
22788
23879
  }
22789
23880
  return compile2(body);
22790
23881
  }
22791
- var GPU_GAMMA_PREAMBLE = `
23882
+ var GPU_GAMMA_PREAMBLE_GLSL = `
22792
23883
  float _gpu_gamma(float z) {
22793
23884
  const float PI = 3.14159265358979;
22794
23885
  // For z < 0.5, use reflection formula with inlined Lanczos (non-recursive)
@@ -22820,7 +23911,37 @@ float _gpu_gammaln(float z) {
22820
23911
  + 1.0 / (1260.0 * z3 * z * z);
22821
23912
  }
22822
23913
  `;
22823
- var GPU_ERF_PREAMBLE = `
23914
+ var GPU_GAMMA_PREAMBLE_WGSL = `
23915
+ fn _gpu_gamma(z: f32) -> f32 {
23916
+ let PI = 3.14159265358979;
23917
+ var w = z;
23918
+ if (z < 0.5) { w = 1.0 - z; }
23919
+ w = w - 1.0;
23920
+ var x = 0.99999999999980993;
23921
+ x = x + 676.5203681218851 / (w + 1.0);
23922
+ x = x + -1259.1392167224028 / (w + 2.0);
23923
+ x = x + 771.32342877765313 / (w + 3.0);
23924
+ x = x + -176.61502916214059 / (w + 4.0);
23925
+ x = x + 12.507343278686905 / (w + 5.0);
23926
+ x = x + -0.13857109526572012 / (w + 6.0);
23927
+ x = x + 9.9843695780195716e-6 / (w + 7.0);
23928
+ x = x + 1.5056327351493116e-7 / (w + 8.0);
23929
+ let t = w + 7.5;
23930
+ let g = sqrt(2.0 * PI) * pow(t, w + 0.5) * exp(-t) * x;
23931
+ if (z < 0.5) { return PI / (sin(PI * z) * g); }
23932
+ return g;
23933
+ }
23934
+
23935
+ fn _gpu_gammaln(z: f32) -> f32 {
23936
+ let z3 = z * z * z;
23937
+ return z * log(z) - z - 0.5 * log(z)
23938
+ + 0.5 * log(2.0 * 3.14159265358979)
23939
+ + 1.0 / (12.0 * z)
23940
+ - 1.0 / (360.0 * z3)
23941
+ + 1.0 / (1260.0 * z3 * z * z);
23942
+ }
23943
+ `;
23944
+ var GPU_ERF_PREAMBLE_GLSL = `
22824
23945
  float _gpu_erf(float x) {
22825
23946
  float ax = abs(x);
22826
23947
  float t = 1.0 / (1.0 + 0.3275911 * ax);
@@ -22838,6 +23959,26 @@ float _gpu_erfinv(float x) {
22838
23959
  float x9 = x7 * x2;
22839
23960
  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);
22840
23961
  }
23962
+ `;
23963
+ var GPU_ERF_PREAMBLE_WGSL = `
23964
+ fn _gpu_erf(x: f32) -> f32 {
23965
+ let ax = abs(x);
23966
+ let t = 1.0 / (1.0 + 0.3275911 * ax);
23967
+ let y = ((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t - 0.284496736) * t + 0.254829592) * t;
23968
+ let result = 1.0 - y * exp(-ax * ax);
23969
+ if (x < 0.0) { return -result; }
23970
+ return result;
23971
+ }
23972
+
23973
+ fn _gpu_erfinv(x: f32) -> f32 {
23974
+ let pi = 3.14159265358979;
23975
+ let x2 = x * x;
23976
+ let x3 = x * x2;
23977
+ let x5 = x3 * x2;
23978
+ let x7 = x5 * x2;
23979
+ let x9 = x7 * x2;
23980
+ 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);
23981
+ }
22841
23982
  `;
22842
23983
  var GPU_HEAVISIDE_PREAMBLE_GLSL = `
22843
23984
  float _gpu_heaviside(float x) {
@@ -24218,8 +25359,10 @@ fn _gpu_apca(lch_bg: vec3f, lch_fg: vec3f) -> f32 {
24218
25359
  };
24219
25360
  let preamble = "";
24220
25361
  preamble += buildComplexPreamble(code, this.languageId);
24221
- if (code.includes("_gpu_gamma")) preamble += GPU_GAMMA_PREAMBLE;
24222
- if (code.includes("_gpu_erf")) preamble += GPU_ERF_PREAMBLE;
25362
+ if (code.includes("_gpu_gamma"))
25363
+ preamble += this.languageId === "wgsl" ? GPU_GAMMA_PREAMBLE_WGSL : GPU_GAMMA_PREAMBLE_GLSL;
25364
+ if (code.includes("_gpu_erf"))
25365
+ preamble += this.languageId === "wgsl" ? GPU_ERF_PREAMBLE_WGSL : GPU_ERF_PREAMBLE_GLSL;
24223
25366
  if (code.includes("_gpu_heaviside"))
24224
25367
  preamble += this.languageId === "wgsl" ? GPU_HEAVISIDE_PREAMBLE_WGSL : GPU_HEAVISIDE_PREAMBLE_GLSL;
24225
25368
  if (code.includes("_gpu_sinc"))
@@ -25005,9 +26148,18 @@ ${code}`;
25005
26148
  return ok({ lo: -xVal.hi, hi: -xVal.lo });
25006
26149
  }
25007
26150
  function _mul(a, b) {
25008
- const products = [a.lo * b.lo, a.lo * b.hi, a.hi * b.lo, a.hi * b.hi];
26151
+ const products = [
26152
+ _prod(a.lo, b.lo),
26153
+ _prod(a.lo, b.hi),
26154
+ _prod(a.hi, b.lo),
26155
+ _prod(a.hi, b.hi)
26156
+ ];
25009
26157
  return { lo: Math.min(...products), hi: Math.max(...products) };
25010
26158
  }
26159
+ function _prod(x, y) {
26160
+ if (x === 0 || y === 0) return 0;
26161
+ return x * y;
26162
+ }
25011
26163
  function mul3(a, b) {
25012
26164
  const unwrapped = unwrapOrPropagate(a, b);
25013
26165
  if (!Array.isArray(unwrapped)) return unwrapped;
@@ -25341,6 +26493,7 @@ ${code}`;
25341
26493
  const period = Math.abs(
25342
26494
  bVal.lo === bVal.hi ? bVal.lo : Math.max(Math.abs(bVal.lo), Math.abs(bVal.hi))
25343
26495
  );
26496
+ const divisorNegative = bVal.hi < 0;
25344
26497
  const flo = Math.floor(aVal.lo / period);
25345
26498
  const fhi = Math.floor(aVal.hi / period);
25346
26499
  if (flo !== fhi) {
@@ -25348,6 +26501,11 @@ ${code}`;
25348
26501
  }
25349
26502
  const modLo = aVal.lo - period * flo;
25350
26503
  const modHi = aVal.hi - period * flo;
26504
+ if (divisorNegative) {
26505
+ if (modLo === 0)
26506
+ return { kind: "singular", at: aVal.lo, continuity: "right" };
26507
+ return ok({ lo: modLo - period, hi: modHi - period });
26508
+ }
25351
26509
  return ok({ lo: Math.min(modLo, modHi), hi: Math.max(modLo, modHi) });
25352
26510
  }
25353
26511
  function remainder(a, b) {
@@ -25379,6 +26537,23 @@ ${code}`;
25379
26537
  const [xVal] = unwrapped;
25380
26538
  return _gamma(xVal);
25381
26539
  }
26540
+ var GAMMA_NEG_EXTREMA_X = [
26541
+ -0.504083008264455,
26542
+ -1.573498473162391,
26543
+ -2.610720868444145,
26544
+ -3.635293366436901,
26545
+ -4.653163765628266,
26546
+ -5.667162441556885,
26547
+ -6.678418213073426,
26548
+ -7.687788325031709,
26549
+ -8.695764163640956,
26550
+ -9.702672540001863
26551
+ ];
26552
+ function gammaNegStripExtremum(lo) {
26553
+ const n = Math.floor(lo);
26554
+ const idx = -n - 1;
26555
+ return idx >= 0 && idx < GAMMA_NEG_EXTREMA_X.length ? GAMMA_NEG_EXTREMA_X[idx] : null;
26556
+ }
25382
26557
  function _gamma(x) {
25383
26558
  if (x.hi >= 0 && x.lo <= 0) {
25384
26559
  return { kind: "singular", at: 0 };
@@ -25391,7 +26566,21 @@ ${code}`;
25391
26566
  }
25392
26567
  const gLo = gamma(x.lo);
25393
26568
  const gHi = gamma(x.hi);
25394
- return ok({ lo: Math.min(gLo, gHi), hi: Math.max(gLo, gHi) });
26569
+ let lo = Math.min(gLo, gHi);
26570
+ let hi = Math.max(gLo, gHi);
26571
+ const xStar = gammaNegStripExtremum(x.lo);
26572
+ if (xStar !== null) {
26573
+ if (xStar >= x.lo && xStar <= x.hi) {
26574
+ const g = gamma(xStar);
26575
+ lo = Math.min(lo, g);
26576
+ hi = Math.max(hi, g);
26577
+ }
26578
+ } else {
26579
+ const stripEven = Math.floor(x.lo) % 2 === 0;
26580
+ if (stripEven) lo = Math.min(lo, 0);
26581
+ else hi = Math.max(hi, 0);
26582
+ }
26583
+ return ok({ lo, hi });
25395
26584
  }
25396
26585
  if (x.lo >= GAMMA_MIN_X) {
25397
26586
  return ok({ lo: gamma(x.lo), hi: gamma(x.hi) });
@@ -25422,7 +26611,15 @@ ${code}`;
25422
26611
  }
25423
26612
  const gLo = gammaln(x.lo);
25424
26613
  const gHi = gammaln(x.hi);
25425
- return ok({ lo: Math.min(gLo, gHi), hi: Math.max(gLo, gHi) });
26614
+ let lo = Math.min(gLo, gHi);
26615
+ const hi = Math.max(gLo, gHi);
26616
+ const xStar = gammaNegStripExtremum(x.lo);
26617
+ if (xStar !== null) {
26618
+ if (xStar >= x.lo && xStar <= x.hi) lo = Math.min(lo, gammaln(xStar));
26619
+ } else {
26620
+ lo = -Infinity;
26621
+ }
26622
+ return ok({ lo, hi });
25426
26623
  }
25427
26624
  return ok({ lo: gammaln(x.lo), hi: gammaln(x.hi) });
25428
26625
  }
@@ -25448,6 +26645,33 @@ ${code}`;
25448
26645
  return ok({ lo: Math.min(fLo, fHi), hi: Math.max(fLo, fHi) });
25449
26646
  return ok({ lo: fLo, hi: fHi });
25450
26647
  }
26648
+ var MAX_INT_ENUM_POINTS = 4096;
26649
+ function integerPoints(lo, hi, cap) {
26650
+ const a = Math.round(lo);
26651
+ const b = Math.round(hi);
26652
+ if (!Number.isFinite(a) || !Number.isFinite(b)) return null;
26653
+ if (b - a + 1 > cap) return null;
26654
+ const out = [];
26655
+ for (let i = a; i <= b; i++) out.push(i);
26656
+ return out;
26657
+ }
26658
+ function enumerateInteger2(a, b, f) {
26659
+ const xs = integerPoints(a.lo, a.hi, MAX_INT_ENUM_POINTS);
26660
+ const ys = integerPoints(b.lo, b.hi, MAX_INT_ENUM_POINTS);
26661
+ if (!xs || !ys || xs.length * ys.length > MAX_INT_ENUM_POINTS) return null;
26662
+ let lo = Infinity;
26663
+ let hi = -Infinity;
26664
+ for (const x of xs)
26665
+ for (const y of ys) {
26666
+ const v = f(x, y);
26667
+ if (Number.isFinite(v)) {
26668
+ if (v < lo) lo = v;
26669
+ if (v > hi) hi = v;
26670
+ }
26671
+ }
26672
+ if (lo === Infinity) return null;
26673
+ return ok({ lo, hi });
26674
+ }
25451
26675
  function binomial(n, k) {
25452
26676
  const uN = unwrapOrPropagate(n);
25453
26677
  if (!Array.isArray(uN)) return uN;
@@ -25455,13 +26679,10 @@ ${code}`;
25455
26679
  if (!Array.isArray(uK)) return uK;
25456
26680
  const [nVal] = uN;
25457
26681
  const [kVal] = uK;
25458
- const vals = [
25459
- choose(Math.round(nVal.lo), Math.round(kVal.lo)),
25460
- choose(Math.round(nVal.lo), Math.round(kVal.hi)),
25461
- choose(Math.round(nVal.hi), Math.round(kVal.lo)),
25462
- choose(Math.round(nVal.hi), Math.round(kVal.hi))
25463
- ];
25464
- return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
26682
+ const enumerated = enumerateInteger2(nVal, kVal, choose);
26683
+ if (enumerated) return enumerated;
26684
+ const nMax = Math.round(nVal.hi);
26685
+ return ok({ lo: 0, hi: choose(nMax, Math.floor(nMax / 2)) });
25465
26686
  }
25466
26687
  function gcd3(a, b) {
25467
26688
  const uA = unwrapOrPropagate(a);
@@ -25470,13 +26691,15 @@ ${code}`;
25470
26691
  if (!Array.isArray(uB)) return uB;
25471
26692
  const [aVal] = uA;
25472
26693
  const [bVal] = uB;
25473
- const vals = [
25474
- gcd(Math.round(aVal.lo), Math.round(bVal.lo)),
25475
- gcd(Math.round(aVal.lo), Math.round(bVal.hi)),
25476
- gcd(Math.round(aVal.hi), Math.round(bVal.lo)),
25477
- gcd(Math.round(aVal.hi), Math.round(bVal.hi))
25478
- ];
25479
- return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
26694
+ const enumerated = enumerateInteger2(aVal, bVal, gcd);
26695
+ if (enumerated) return enumerated;
26696
+ const m = Math.max(
26697
+ Math.abs(Math.round(aVal.lo)),
26698
+ Math.abs(Math.round(aVal.hi)),
26699
+ Math.abs(Math.round(bVal.lo)),
26700
+ Math.abs(Math.round(bVal.hi))
26701
+ );
26702
+ return ok({ lo: 0, hi: m });
25480
26703
  }
25481
26704
  function lcm3(a, b) {
25482
26705
  const uA = unwrapOrPropagate(a);
@@ -25485,13 +26708,11 @@ ${code}`;
25485
26708
  if (!Array.isArray(uB)) return uB;
25486
26709
  const [aVal] = uA;
25487
26710
  const [bVal] = uB;
25488
- const vals = [
25489
- lcm(Math.round(aVal.lo), Math.round(bVal.lo)),
25490
- lcm(Math.round(aVal.lo), Math.round(bVal.hi)),
25491
- lcm(Math.round(aVal.hi), Math.round(bVal.lo)),
25492
- lcm(Math.round(aVal.hi), Math.round(bVal.hi))
25493
- ];
25494
- return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
26711
+ const enumerated = enumerateInteger2(aVal, bVal, lcm);
26712
+ if (enumerated) return enumerated;
26713
+ const ma = Math.max(Math.abs(Math.round(aVal.lo)), Math.abs(Math.round(aVal.hi)));
26714
+ const mb = Math.max(Math.abs(Math.round(bVal.lo)), Math.abs(Math.round(bVal.hi)));
26715
+ return ok({ lo: 0, hi: ma * mb });
25495
26716
  }
25496
26717
  function chop2(x) {
25497
26718
  const unwrapped = unwrapOrPropagate(x);
@@ -25883,7 +27104,6 @@ ${code}`;
25883
27104
  29.8116,
25884
27105
  32.95639
25885
27106
  ];
25886
- var SINC_GLOBAL_LO = -0.21724;
25887
27107
  function sinc2(x) {
25888
27108
  const unwrapped = unwrapOrPropagate(x);
25889
27109
  if (!Array.isArray(unwrapped)) return unwrapped;
@@ -25904,8 +27124,14 @@ ${code}`;
25904
27124
  if (e >= xVal.lo && e <= xVal.hi) update(sincVal(e));
25905
27125
  if (-e >= xVal.lo && -e <= xVal.hi) update(sincVal(-e));
25906
27126
  }
25907
- if (Math.abs(xVal.lo) > lastExtremum || Math.abs(xVal.hi) > lastExtremum) {
25908
- update(SINC_GLOBAL_LO);
27127
+ let minBeyondAbs = Infinity;
27128
+ if (xVal.hi > lastExtremum)
27129
+ minBeyondAbs = Math.min(minBeyondAbs, Math.max(xVal.lo, lastExtremum));
27130
+ if (xVal.lo < -lastExtremum)
27131
+ minBeyondAbs = Math.min(minBeyondAbs, -Math.min(xVal.hi, -lastExtremum));
27132
+ if (Number.isFinite(minBeyondAbs) && minBeyondAbs > 0) {
27133
+ update(1 / minBeyondAbs);
27134
+ update(-1 / minBeyondAbs);
25909
27135
  }
25910
27136
  return ok({ lo, hi });
25911
27137
  }
@@ -25931,8 +27157,21 @@ ${code}`;
25931
27157
  if (e >= xVal.lo && e <= xVal.hi) update(fresnelS(e));
25932
27158
  if (-e >= xVal.lo && -e <= xVal.hi) update(fresnelS(-e));
25933
27159
  }
27160
+ fresnelConvergenceBound(xVal, FRESNEL_S_EXTREMA, fresnelS, update);
25934
27161
  return ok({ lo, hi });
25935
27162
  }
27163
+ function fresnelConvergenceBound(xVal, extrema, scalar, update) {
27164
+ const lastE = extrema[extrema.length - 1];
27165
+ const amp = Math.abs(scalar(lastE) - 0.5);
27166
+ if (xVal.hi > lastE) {
27167
+ update(0.5 + amp);
27168
+ update(0.5 - amp);
27169
+ }
27170
+ if (xVal.lo < -lastE) {
27171
+ update(-0.5 - amp);
27172
+ update(-0.5 + amp);
27173
+ }
27174
+ }
25936
27175
  function fresnelC2(x) {
25937
27176
  const unwrapped = unwrapOrPropagate(x);
25938
27177
  if (!Array.isArray(unwrapped)) return unwrapped;
@@ -25949,6 +27188,7 @@ ${code}`;
25949
27188
  if (e >= xVal.lo && e <= xVal.hi) update(fresnelC(e));
25950
27189
  if (-e >= xVal.lo && -e <= xVal.hi) update(fresnelC(-e));
25951
27190
  }
27191
+ fresnelConvergenceBound(xVal, FRESNEL_C_EXTREMA, fresnelC, update);
25952
27192
  return ok({ lo, hi });
25953
27193
  }
25954
27194
 
@@ -26056,11 +27296,9 @@ ${code}`;
26056
27296
  const unwrapped = unwrapOrPropagate(x, lo, hi);
26057
27297
  if (!Array.isArray(unwrapped)) return unwrapped;
26058
27298
  const [xVal, loVal, hiVal] = unwrapped;
26059
- const resultLo = Math.max(xVal.lo, loVal.lo);
26060
- const resultHi = Math.min(xVal.hi, hiVal.hi);
26061
- if (resultLo > resultHi) {
26062
- return { kind: "empty" };
26063
- }
27299
+ const lowered = { lo: Math.max(xVal.lo, loVal.lo), hi: Math.max(xVal.hi, loVal.hi) };
27300
+ const resultLo = Math.min(lowered.lo, hiVal.lo);
27301
+ const resultHi = Math.min(lowered.hi, hiVal.hi);
26064
27302
  return { kind: "interval", value: { lo: resultLo, hi: resultHi } };
26065
27303
  }
26066
27304
 
@@ -26393,7 +27631,7 @@ ${code}`;
26393
27631
  function compileIntervalBound(expr, numVal, target) {
26394
27632
  if (numVal !== void 0) return String(numVal);
26395
27633
  const compiled = BaseCompiler.compile(expr, target);
26396
- return `Math.floor((${compiled}).hi)`;
27634
+ return `Math.floor(((_b) => (_b && _b.value ? _b.value.hi : _b.hi))(${compiled}))`;
26397
27635
  }
26398
27636
  function compileIntervalSumProduct(kind, args, _compile, target) {
26399
27637
  if (!args[0]) throw new Error(`${kind}: no body`);
@@ -26579,7 +27817,7 @@ ${code}`;
26579
27817
  }
26580
27818
 
26581
27819
  // src/compile.ts
26582
- var version = "0.58.0";
27820
+ var version = "0.59.0";
26583
27821
  return __toCommonJS(compile_exports);
26584
27822
  })();
26585
27823
  /*! Bundled license information: