solve-engine 1.0.0-beta.7 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/{BytecodeBuilder-3egMyuDi.d.cts → BytecodeBuilder-B0xskcv5.d.cts} +2 -1
  2. package/dist/{BytecodeBuilder-3egMyuDi.d.ts → BytecodeBuilder-B0xskcv5.d.ts} +2 -1
  3. package/dist/{Configuration-fVpd-HC-.d.cts → Configuration-B-G5gTRn.d.cts} +107 -29
  4. package/dist/{Configuration-fVpd-HC-.d.ts → Configuration-B-G5gTRn.d.ts} +107 -29
  5. package/dist/{EngineError-DvPSnhZi.d.cts → EngineError-LU7W7AgI.d.cts} +96 -16
  6. package/dist/{EngineError-DvPSnhZi.d.ts → EngineError-LU7W7AgI.d.ts} +96 -16
  7. package/dist/{Lexer-W9MBOP0V.d.ts → Lexer-BN5mt30n.d.ts} +16 -0
  8. package/dist/{Lexer-Cfm79Dak.d.cts → Lexer-D78E2yDW.d.cts} +16 -0
  9. package/dist/{PackageRegistry-pHtKythi.d.cts → PackageRegistry-B37mRvvz.d.cts} +69 -13
  10. package/dist/{PackageRegistry-CjDt-Jy_.d.ts → PackageRegistry-DCUEzbQt.d.ts} +69 -13
  11. package/dist/{Parselet-DEdF9I7n.d.ts → Parselet-BaySkMV3.d.ts} +37 -5
  12. package/dist/{Parselet-Cu0bLSis.d.cts → Parselet-DuI1Pjiq.d.cts} +37 -5
  13. package/dist/{ScopeManager-CKfQtl7l.d.cts → ScopeManager-B6GzdhVG.d.cts} +75 -6
  14. package/dist/{ScopeManager-B5k0nk05.d.ts → ScopeManager-udv4Twwq.d.ts} +75 -6
  15. package/dist/{VMCheckpoints-BmDwIXgK.d.ts → VMCheckpoints-BiaIlOOY.d.ts} +4 -4
  16. package/dist/{VMCheckpoints-CqFuLwrT.d.cts → VMCheckpoints-DwLjivM7.d.cts} +4 -4
  17. package/dist/{Value-KtAQNHur.d.cts → Value-CXJqDH9J.d.cts} +5 -2
  18. package/dist/{Value-KtAQNHur.d.ts → Value-CXJqDH9J.d.ts} +5 -2
  19. package/dist/{chunk-35IWNZPJ.cjs → chunk-2XLQPQKI.cjs} +58 -27
  20. package/dist/chunk-2XLQPQKI.cjs.map +1 -0
  21. package/dist/{chunk-CSG5XVNJ.cjs → chunk-3AFRJYP4.cjs} +556 -414
  22. package/dist/chunk-3AFRJYP4.cjs.map +1 -0
  23. package/dist/chunk-3BOK2LDK.js +17 -0
  24. package/dist/chunk-3BOK2LDK.js.map +1 -0
  25. package/dist/{chunk-6RDSQURE.js → chunk-3D7V24DG.js} +57 -6
  26. package/dist/chunk-3D7V24DG.js.map +1 -0
  27. package/dist/{chunk-MEOHSQEH.js → chunk-3LAEG75D.js} +47 -15
  28. package/dist/chunk-3LAEG75D.js.map +1 -0
  29. package/dist/{chunk-4AVD7NZW.cjs → chunk-4B2CNWQU.cjs} +13 -7
  30. package/dist/chunk-4B2CNWQU.cjs.map +1 -0
  31. package/dist/{chunk-6GCKCWLB.js → chunk-526PMQOA.js} +126 -69
  32. package/dist/chunk-526PMQOA.js.map +1 -0
  33. package/dist/{chunk-2CS6OMZK.js → chunk-5F4C26RU.js} +8 -5
  34. package/dist/chunk-5F4C26RU.js.map +1 -0
  35. package/dist/{chunk-M4N5GA5Z.cjs → chunk-5KMIY374.cjs} +57 -6
  36. package/dist/chunk-5KMIY374.cjs.map +1 -0
  37. package/dist/{chunk-R24DI24X.cjs → chunk-5LI5EPGJ.cjs} +6 -5
  38. package/dist/chunk-5LI5EPGJ.cjs.map +1 -0
  39. package/dist/{chunk-BAMZT3GL.js → chunk-5WVP4YHP.js} +939 -134
  40. package/dist/chunk-5WVP4YHP.js.map +1 -0
  41. package/dist/{chunk-MZOVP3WI.cjs → chunk-6KFYJ6TD.cjs} +3 -2
  42. package/dist/chunk-6KFYJ6TD.cjs.map +1 -0
  43. package/dist/{chunk-BXKJLM5R.cjs → chunk-6WFMPTGB.cjs} +972 -636
  44. package/dist/chunk-6WFMPTGB.cjs.map +1 -0
  45. package/dist/{chunk-2MV4HBKC.cjs → chunk-A2N2GFCG.cjs} +10 -10
  46. package/dist/{chunk-2MV4HBKC.cjs.map → chunk-A2N2GFCG.cjs.map} +1 -1
  47. package/dist/chunk-ADBA3XBE.cjs +20 -0
  48. package/dist/chunk-ADBA3XBE.cjs.map +1 -0
  49. package/dist/{chunk-MBNQVDVC.cjs → chunk-AMOJYLG2.cjs} +16 -10
  50. package/dist/chunk-AMOJYLG2.cjs.map +1 -0
  51. package/dist/{chunk-CLVQBF5C.cjs → chunk-AQNHHJMJ.cjs} +5 -5
  52. package/dist/{chunk-CLVQBF5C.cjs.map → chunk-AQNHHJMJ.cjs.map} +1 -1
  53. package/dist/{chunk-V6HA6JJZ.cjs → chunk-B7TLZABL.cjs} +242 -138
  54. package/dist/chunk-B7TLZABL.cjs.map +1 -0
  55. package/dist/{chunk-AHCLWAM5.cjs → chunk-BHTNFEGZ.cjs} +13 -13
  56. package/dist/chunk-BHTNFEGZ.cjs.map +1 -0
  57. package/dist/{chunk-BVAR5J2F.js → chunk-GQCOSXMG.js} +117 -6
  58. package/dist/chunk-GQCOSXMG.js.map +1 -0
  59. package/dist/{chunk-QDMPOAI7.cjs → chunk-HDP7VK3C.cjs} +1118 -313
  60. package/dist/chunk-HDP7VK3C.cjs.map +1 -0
  61. package/dist/{chunk-GVWHCL2N.js → chunk-HMOISHXR.js} +217 -75
  62. package/dist/chunk-HMOISHXR.js.map +1 -0
  63. package/dist/{chunk-MTX2KVU7.cjs → chunk-HVQFNJKE.cjs} +122 -90
  64. package/dist/chunk-HVQFNJKE.cjs.map +1 -0
  65. package/dist/{chunk-OC6LTXYS.cjs → chunk-JMXUNXQS.cjs} +126 -7
  66. package/dist/chunk-JMXUNXQS.cjs.map +1 -0
  67. package/dist/{chunk-WWOLFXTX.cjs → chunk-KBSXGXPM.cjs} +10 -7
  68. package/dist/chunk-KBSXGXPM.cjs.map +1 -0
  69. package/dist/{chunk-YU2CUNFO.js → chunk-KV7UW6T6.js} +11 -5
  70. package/dist/chunk-KV7UW6T6.js.map +1 -0
  71. package/dist/{chunk-CCJPSHGI.cjs → chunk-N7FNVFXW.cjs} +4 -12
  72. package/dist/chunk-N7FNVFXW.cjs.map +1 -0
  73. package/dist/{chunk-CYFK5SY2.js → chunk-O3ANBHSA.js} +169 -39
  74. package/dist/chunk-O3ANBHSA.js.map +1 -0
  75. package/dist/{chunk-NZFKROS7.cjs → chunk-PA4VC73I.cjs} +130 -72
  76. package/dist/chunk-PA4VC73I.cjs.map +1 -0
  77. package/dist/{chunk-NJTXJ5AG.cjs → chunk-PFUESQTW.cjs} +18 -18
  78. package/dist/{chunk-NJTXJ5AG.cjs.map → chunk-PFUESQTW.cjs.map} +1 -1
  79. package/dist/{chunk-SFQWJMKT.js → chunk-QY25VWBF.js} +51 -12
  80. package/dist/chunk-QY25VWBF.js.map +1 -0
  81. package/dist/{chunk-WC5FFSHB.js → chunk-R3PY4G7J.js} +3 -3
  82. package/dist/{chunk-WC5FFSHB.js.map → chunk-R3PY4G7J.js.map} +1 -1
  83. package/dist/{chunk-M5E34VG5.js → chunk-SBUFNJVE.js} +3 -3
  84. package/dist/{chunk-M5E34VG5.js.map → chunk-SBUFNJVE.js.map} +1 -1
  85. package/dist/{chunk-P33SBYGG.js → chunk-TBN7DEHO.js} +54 -23
  86. package/dist/chunk-TBN7DEHO.js.map +1 -0
  87. package/dist/{chunk-UKPGSAZW.js → chunk-TMA4RCEN.js} +3 -3
  88. package/dist/{chunk-UKPGSAZW.js.map → chunk-TMA4RCEN.js.map} +1 -1
  89. package/dist/{chunk-DUEZFTK2.js → chunk-UKQHXPGW.js} +4 -12
  90. package/dist/chunk-UKQHXPGW.js.map +1 -0
  91. package/dist/{chunk-4CVLFLOB.cjs → chunk-UM6BVY2S.cjs} +201 -69
  92. package/dist/chunk-UM6BVY2S.cjs.map +1 -0
  93. package/dist/{chunk-75JP4BZX.js → chunk-UQ3UIZJC.js} +3 -2
  94. package/dist/chunk-UQ3UIZJC.js.map +1 -0
  95. package/dist/{chunk-PCPX42KL.js → chunk-V4XG5QF6.js} +16 -10
  96. package/dist/chunk-V4XG5QF6.js.map +1 -0
  97. package/dist/{chunk-P75775WC.js → chunk-V5PYO44Y.js} +145 -41
  98. package/dist/chunk-V5PYO44Y.js.map +1 -0
  99. package/dist/{chunk-GPPLSM2Z.js → chunk-VB37OC6I.js} +6 -5
  100. package/dist/chunk-VB37OC6I.js.map +1 -0
  101. package/dist/{chunk-MVBEL57Q.js → chunk-Y7FT4IQT.js} +500 -170
  102. package/dist/chunk-Y7FT4IQT.js.map +1 -0
  103. package/dist/{chunk-OFXOTECC.js → chunk-YPPPYLSR.js} +7 -7
  104. package/dist/chunk-YPPPYLSR.js.map +1 -0
  105. package/dist/{chunk-M4F66R4O.cjs → chunk-YWQ6V4ZN.cjs} +121 -82
  106. package/dist/chunk-YWQ6V4ZN.cjs.map +1 -0
  107. package/dist/constants.cjs +5 -5
  108. package/dist/constants.d.cts +1 -1
  109. package/dist/constants.d.ts +1 -1
  110. package/dist/constants.js +2 -2
  111. package/dist/engine.cjs +31 -31
  112. package/dist/engine.d.cts +11 -11
  113. package/dist/engine.d.ts +11 -11
  114. package/dist/engine.js +21 -21
  115. package/dist/errors.cjs +19 -19
  116. package/dist/errors.d.cts +2 -2
  117. package/dist/errors.d.ts +2 -2
  118. package/dist/errors.js +1 -1
  119. package/dist/format.cjs +29 -22
  120. package/dist/format.cjs.map +1 -1
  121. package/dist/format.d.cts +1 -2
  122. package/dist/format.d.ts +1 -2
  123. package/dist/format.js +23 -16
  124. package/dist/format.js.map +1 -1
  125. package/dist/index.cjs +31 -31
  126. package/dist/index.d.cts +10 -10
  127. package/dist/index.d.ts +10 -10
  128. package/dist/index.js +22 -22
  129. package/dist/language.cjs +8 -8
  130. package/dist/language.cjs.map +1 -1
  131. package/dist/language.d.cts +10 -10
  132. package/dist/language.d.ts +10 -10
  133. package/dist/language.js +6 -6
  134. package/dist/language.js.map +1 -1
  135. package/dist/lexer.cjs +18 -18
  136. package/dist/lexer.d.cts +2 -2
  137. package/dist/lexer.d.ts +2 -2
  138. package/dist/lexer.js +6 -6
  139. package/dist/normalizer.cjs +12 -12
  140. package/dist/normalizer.js +6 -6
  141. package/dist/packages.cjs +39 -39
  142. package/dist/packages.d.cts +9 -9
  143. package/dist/packages.d.ts +9 -9
  144. package/dist/packages.js +16 -16
  145. package/dist/parser.cjs +15 -15
  146. package/dist/parser.d.cts +23 -9
  147. package/dist/parser.d.ts +23 -9
  148. package/dist/parser.js +5 -5
  149. package/dist/{pipeline-CrsRPmsv.d.ts → pipeline-B6k5lCB7.d.ts} +1 -1
  150. package/dist/{pipeline-DPUQt7yL.d.cts → pipeline-BEb3hujr.d.cts} +1 -1
  151. package/dist/resolvers.d.cts +2 -2
  152. package/dist/resolvers.d.ts +2 -2
  153. package/dist/uom.cjs +17 -17
  154. package/dist/uom.d.cts +2 -2
  155. package/dist/uom.d.ts +2 -2
  156. package/dist/uom.js +7 -7
  157. package/dist/utilities.cjs +8 -4
  158. package/dist/utilities.d.cts +19 -3
  159. package/dist/utilities.d.ts +19 -3
  160. package/dist/utilities.js +2 -2
  161. package/dist/vm.cjs +43 -31
  162. package/dist/vm.d.cts +105 -9
  163. package/dist/vm.d.ts +105 -9
  164. package/dist/vm.js +9 -9
  165. package/package.json +1 -1
  166. package/dist/chunk-2CS6OMZK.js.map +0 -1
  167. package/dist/chunk-35IWNZPJ.cjs.map +0 -1
  168. package/dist/chunk-4AVD7NZW.cjs.map +0 -1
  169. package/dist/chunk-4CVLFLOB.cjs.map +0 -1
  170. package/dist/chunk-6GCKCWLB.js.map +0 -1
  171. package/dist/chunk-6RDSQURE.js.map +0 -1
  172. package/dist/chunk-75JP4BZX.js.map +0 -1
  173. package/dist/chunk-AHCLWAM5.cjs.map +0 -1
  174. package/dist/chunk-BAMZT3GL.js.map +0 -1
  175. package/dist/chunk-BVAR5J2F.js.map +0 -1
  176. package/dist/chunk-BXKJLM5R.cjs.map +0 -1
  177. package/dist/chunk-CCJPSHGI.cjs.map +0 -1
  178. package/dist/chunk-CSG5XVNJ.cjs.map +0 -1
  179. package/dist/chunk-CYFK5SY2.js.map +0 -1
  180. package/dist/chunk-DUEZFTK2.js.map +0 -1
  181. package/dist/chunk-GPPLSM2Z.js.map +0 -1
  182. package/dist/chunk-GVWHCL2N.js.map +0 -1
  183. package/dist/chunk-M4F66R4O.cjs.map +0 -1
  184. package/dist/chunk-M4N5GA5Z.cjs.map +0 -1
  185. package/dist/chunk-MBNQVDVC.cjs.map +0 -1
  186. package/dist/chunk-MEOHSQEH.js.map +0 -1
  187. package/dist/chunk-MTX2KVU7.cjs.map +0 -1
  188. package/dist/chunk-MVBEL57Q.js.map +0 -1
  189. package/dist/chunk-MZOVP3WI.cjs.map +0 -1
  190. package/dist/chunk-N5YFR4UP.cjs +0 -10
  191. package/dist/chunk-N5YFR4UP.cjs.map +0 -1
  192. package/dist/chunk-NZFKROS7.cjs.map +0 -1
  193. package/dist/chunk-OC6LTXYS.cjs.map +0 -1
  194. package/dist/chunk-OFXOTECC.js.map +0 -1
  195. package/dist/chunk-P33SBYGG.js.map +0 -1
  196. package/dist/chunk-P75775WC.js.map +0 -1
  197. package/dist/chunk-PCPX42KL.js.map +0 -1
  198. package/dist/chunk-PFSDGGYL.js +0 -8
  199. package/dist/chunk-PFSDGGYL.js.map +0 -1
  200. package/dist/chunk-QDMPOAI7.cjs.map +0 -1
  201. package/dist/chunk-R24DI24X.cjs.map +0 -1
  202. package/dist/chunk-SFQWJMKT.js.map +0 -1
  203. package/dist/chunk-V6HA6JJZ.cjs.map +0 -1
  204. package/dist/chunk-WWOLFXTX.cjs.map +0 -1
  205. package/dist/chunk-YU2CUNFO.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { boolValue, symbolicValue, numberValue, matrixValue, errorValue } from './chunk-BVAR5J2F.js';
2
- import { ErrorFactory } from './chunk-6RDSQURE.js';
1
+ import { boolValue, symbolicValue, numberValue, matrixValue, errorValue, checkedArray, faultedOperand } from './chunk-GQCOSXMG.js';
2
+ import { ErrorFactory } from './chunk-3D7V24DG.js';
3
3
 
4
4
  // src/symbolic/Rational.ts
5
5
  var RATIONAL_ZERO = { n: 0n, d: 1n };
@@ -732,6 +732,17 @@ function divideOutConstant(numerator, denominator, original) {
732
732
  }
733
733
  return { kind: "div", left: fromPolynomial(numerator), right: fromPolynomial(denominator) };
734
734
  }
735
+ function squareFreePart(coefficients) {
736
+ const trimmed = trim([...coefficients]);
737
+ if (trimmed.length <= 1) return monic(trimmed);
738
+ const derivative = [];
739
+ for (let power = 1; power < trimmed.length; power++) {
740
+ derivative.push(rationalMul(trimmed[power], { n: BigInt(power), d: 1n }));
741
+ }
742
+ const shared = coefficientGcd(trimmed, derivative);
743
+ if (shared.length <= 1) return monic(trimmed);
744
+ return monic(polynomialDivide(trimmed, shared).quotient);
745
+ }
735
746
 
736
747
  // src/symbolic/Radicals.ts
737
748
  function exactIntegerSqrt(value) {
@@ -787,14 +798,15 @@ function signedSurdNode(value) {
787
798
  }
788
799
 
789
800
  // src/symbolic/Simplify.ts
790
- function flattenSum(node, negated, out) {
801
+ function flattenSum(node, negated, out, depth = 0) {
802
+ if (depth >= MAX_SIMPLIFY_DEPTH) return false;
791
803
  switch (node.kind) {
792
804
  case "add":
793
- return flattenSum(node.left, negated, out) && flattenSum(node.right, negated, out);
805
+ return flattenSum(node.left, negated, out, depth + 1) && flattenSum(node.right, negated, out, depth + 1);
794
806
  case "sub":
795
- return flattenSum(node.left, negated, out) && flattenSum(node.right, !negated, out);
807
+ return flattenSum(node.left, negated, out, depth + 1) && flattenSum(node.right, !negated, out, depth + 1);
796
808
  case "neg":
797
- return flattenSum(node.operand, !negated, out);
809
+ return flattenSum(node.operand, !negated, out, depth + 1);
798
810
  case "const":
799
811
  out.push({ coeff: negated ? rationalNeg(node.value) : node.value, name: null });
800
812
  return true;
@@ -917,7 +929,21 @@ function simplifySymbolic(node) {
917
929
  { limit: SYMBOLIC_MAX_NODES }
918
930
  );
919
931
  }
920
- return simplifyNode(node);
932
+ const depthOnEntry = walkDepth;
933
+ try {
934
+ return simplifyNode(node);
935
+ } finally {
936
+ walkDepth = depthOnEntry;
937
+ }
938
+ }
939
+ var MAX_SIMPLIFY_DEPTH = 900;
940
+ var walkDepth = 0;
941
+ function simplifyNode(node) {
942
+ if (walkDepth >= MAX_SIMPLIFY_DEPTH) return node;
943
+ walkDepth++;
944
+ const simplified = simplifyNodeAt(node);
945
+ walkDepth--;
946
+ return simplified;
921
947
  }
922
948
  function asComplex(node) {
923
949
  if (node.kind === "complex") return node.value;
@@ -972,7 +998,7 @@ function foldComplexCall(name, args) {
972
998
  return null;
973
999
  }
974
1000
  }
975
- function simplifyNode(node) {
1001
+ function simplifyNodeAt(node) {
976
1002
  switch (node.kind) {
977
1003
  case "const":
978
1004
  case "complex":
@@ -1116,7 +1142,10 @@ function formatCoefficient(coeff, text) {
1116
1142
  if (coeff.n === -1n && coeff.d === 1n) return `-${text}`;
1117
1143
  return `${formatRational(coeff)}${text}`;
1118
1144
  }
1119
- function formatFactor(node) {
1145
+ var MAX_FORMAT_DEPTH = 600;
1146
+ var ELIDED = "...";
1147
+ function formatFactor(node, depth) {
1148
+ if (depth >= MAX_FORMAT_DEPTH) return ELIDED;
1120
1149
  switch (node.kind) {
1121
1150
  case "const":
1122
1151
  return formatRational(node.value);
@@ -1126,43 +1155,50 @@ function formatFactor(node) {
1126
1155
  return node.name;
1127
1156
  case "add":
1128
1157
  case "sub":
1129
- return `(${formatSymbolic(node)})`;
1158
+ return `(${formatSum(node, depth)})`;
1130
1159
  case "neg":
1131
- return `-${formatFactor(node.operand)}`;
1160
+ return `-${formatFactor(node.operand, depth + 1)}`;
1132
1161
  case "call":
1133
- return `${node.name}(${node.args.map(formatSymbolic).join(", ")})`;
1162
+ return `${node.name}(${node.args.map((arg) => formatSum(arg, depth + 1)).join(", ")})`;
1134
1163
  case "pow": {
1135
- const base = isAtomic(node.base) ? formatFactor(node.base) : `(${formatSymbolic(node.base)})`;
1136
- const exponent = isAtomic(node.exponent) ? formatFactor(node.exponent) : `(${formatSymbolic(node.exponent)})`;
1164
+ const base = isAtomic(node.base) ? formatFactor(node.base, depth + 1) : `(${formatSum(node.base, depth + 1)})`;
1165
+ const exponent = isAtomic(node.exponent) ? formatFactor(node.exponent, depth + 1) : `(${formatSum(node.exponent, depth + 1)})`;
1137
1166
  return `${base}^${exponent}`;
1138
1167
  }
1139
1168
  case "mul": {
1140
1169
  const coeffVar = tryExtractCoeffVar(node);
1141
1170
  if (coeffVar) return formatCoefficient(coeffVar.coeff, coeffVar.name);
1142
1171
  const coeffPow = tryExtractCoeffPow(node);
1143
- if (coeffPow) return formatCoefficient(coeffPow.coeff, formatFactor(coeffPow.power));
1172
+ if (coeffPow) return formatCoefficient(coeffPow.coeff, formatFactor(coeffPow.power, depth + 1));
1144
1173
  if (node.left.kind === "const" && node.right.kind === "mul") {
1145
- const inner = formatFactor(node.right);
1174
+ const inner = formatFactor(node.right, depth + 1);
1146
1175
  if (!/^[\d.]/.test(inner)) return formatCoefficient(node.left.value, inner);
1147
1176
  }
1148
- return `${formatFactor(node.left)}*${formatFactor(node.right)}`;
1177
+ return `${formatFactor(node.left, depth + 1)}*${formatFactor(node.right, depth + 1)}`;
1178
+ }
1179
+ case "div": {
1180
+ const denominator = formatFactor(node.right, depth + 1);
1181
+ const needsBrackets = node.right.kind === "mul" || node.right.kind === "div";
1182
+ return `${formatFactor(node.left, depth + 1)}/${needsBrackets ? `(${denominator})` : denominator}`;
1149
1183
  }
1150
- case "div":
1151
- return `${formatFactor(node.left)}/${formatFactor(node.right)}`;
1152
1184
  }
1153
1185
  }
1154
- function collectDisplayTerms(node, negated, out) {
1186
+ function collectDisplayTerms(node, negated, out, depth) {
1187
+ if (depth >= MAX_FORMAT_DEPTH) {
1188
+ out.push({ negated, text: ELIDED });
1189
+ return;
1190
+ }
1155
1191
  switch (node.kind) {
1156
1192
  case "add":
1157
- collectDisplayTerms(node.left, negated, out);
1158
- collectDisplayTerms(node.right, negated, out);
1193
+ collectDisplayTerms(node.left, negated, out, depth + 1);
1194
+ collectDisplayTerms(node.right, negated, out, depth + 1);
1159
1195
  return;
1160
1196
  case "sub":
1161
- collectDisplayTerms(node.left, negated, out);
1162
- collectDisplayTerms(node.right, !negated, out);
1197
+ collectDisplayTerms(node.left, negated, out, depth + 1);
1198
+ collectDisplayTerms(node.right, !negated, out, depth + 1);
1163
1199
  return;
1164
1200
  case "neg":
1165
- collectDisplayTerms(node.operand, !negated, out);
1201
+ collectDisplayTerms(node.operand, !negated, out, depth + 1);
1166
1202
  return;
1167
1203
  case "const": {
1168
1204
  if (node.value.n === 0n) return;
@@ -1186,7 +1222,7 @@ function collectDisplayTerms(node, negated, out) {
1186
1222
  return;
1187
1223
  }
1188
1224
  default: {
1189
- const text = formatFactor(node);
1225
+ const text = formatFactor(node, depth);
1190
1226
  const liftsSign = (node.kind === "mul" || node.kind === "div") && text.startsWith("-");
1191
1227
  if (liftsSign) out.push({ negated: !negated, text: text.slice(1) });
1192
1228
  else out.push({ negated, text });
@@ -1194,8 +1230,16 @@ function collectDisplayTerms(node, negated, out) {
1194
1230
  }
1195
1231
  }
1196
1232
  function formatSymbolic(node) {
1233
+ try {
1234
+ return formatSum(node, 0);
1235
+ } catch (thrown) {
1236
+ if (thrown instanceof RangeError) return ELIDED;
1237
+ throw thrown;
1238
+ }
1239
+ }
1240
+ function formatSum(node, depth) {
1197
1241
  const terms = [];
1198
- collectDisplayTerms(node, false, terms);
1242
+ collectDisplayTerms(node, false, terms, depth);
1199
1243
  if (terms.length === 0) return "0";
1200
1244
  let out = "";
1201
1245
  terms.forEach((term, index) => {
@@ -1276,7 +1320,7 @@ function matrixMultiply(l, r) {
1276
1320
  }
1277
1321
  const resultRows = l.rows;
1278
1322
  const resultCols = r.cols;
1279
- const data = new Array(resultRows * resultCols);
1323
+ const data = checkedArray(resultRows * resultCols, "matrix cells");
1280
1324
  for (let row = 0; row < resultRows; row++) {
1281
1325
  for (let col = 0; col < resultCols; col++) {
1282
1326
  if (useSymbolic) {
@@ -1297,6 +1341,37 @@ function matrixMultiply(l, r) {
1297
1341
  }
1298
1342
  return matrixValue(resultRows, resultCols, data);
1299
1343
  }
1344
+ function matrixPower(m, exponent) {
1345
+ if (!isSquare(m)) {
1346
+ return errorValue("MATRIX_POWER_REQUIRES_SQUARE_MATRIX", `^: only a square matrix can be raised to a power (got ${m.rows}x${m.cols}).`);
1347
+ }
1348
+ if (!Number.isInteger(exponent) || exponent < 0) {
1349
+ return errorValue(
1350
+ "MATRIX_POWER_REQUIRES_WHOLE_EXPONENT",
1351
+ `^: a matrix can only be raised to a whole number of 0 or more (got ${exponent}); "^-1" means the inverse and "^T" the transpose.`
1352
+ );
1353
+ }
1354
+ const n = m.rows;
1355
+ const identity = new Array(n * n).fill(0);
1356
+ for (let i = 0; i < n; i++) identity[i + i * n] = 1;
1357
+ let accumulated = { rows: n, cols: n, data: identity, hasSymbolic: false };
1358
+ let squared = m;
1359
+ let remaining = exponent;
1360
+ while (remaining > 0) {
1361
+ if (remaining % 2 === 1) {
1362
+ const product = matrixMultiply(accumulated, squared);
1363
+ if (product.type === 13 /* Error */) return product;
1364
+ accumulated = product.value;
1365
+ }
1366
+ remaining = Math.floor(remaining / 2);
1367
+ if (remaining > 0) {
1368
+ const doubled = matrixMultiply(squared, squared);
1369
+ if (doubled.type === 13 /* Error */) return doubled;
1370
+ squared = doubled.value;
1371
+ }
1372
+ }
1373
+ return matrixValue(accumulated.rows, accumulated.cols, accumulated.data);
1374
+ }
1300
1375
  function matrixCompare(l, r, cmp) {
1301
1376
  if (!sameShape(l, r)) {
1302
1377
  return errorValue(
@@ -1326,7 +1401,52 @@ function toWorkingRows(m) {
1326
1401
  }
1327
1402
  return rows;
1328
1403
  }
1404
+ var EXACT_DETERMINANT_DIMENSION_LIMIT = 12;
1405
+ function toIntegerRows(m) {
1406
+ if (m.rows > EXACT_DETERMINANT_DIMENSION_LIMIT) return null;
1407
+ const rows = [];
1408
+ for (let r = 0; r < m.rows; r++) {
1409
+ const row = [];
1410
+ for (let c = 0; c < m.cols; c++) {
1411
+ const cell = matAt(m, r, c);
1412
+ if (typeof cell !== "number" || !Number.isSafeInteger(cell)) return null;
1413
+ row.push(BigInt(cell));
1414
+ }
1415
+ rows.push(row);
1416
+ }
1417
+ return rows;
1418
+ }
1419
+ function integerDeterminant(rows) {
1420
+ const n = rows.length;
1421
+ let previous = 1n;
1422
+ let sign = 1n;
1423
+ for (let k = 0; k < n - 1; k++) {
1424
+ if (rows[k][k] === 0n) {
1425
+ let candidate = -1;
1426
+ for (let r = k + 1; r < n; r++) {
1427
+ if (rows[r][k] !== 0n) {
1428
+ candidate = r;
1429
+ break;
1430
+ }
1431
+ }
1432
+ if (candidate === -1) return 0n;
1433
+ const swapped = rows[k];
1434
+ rows[k] = rows[candidate];
1435
+ rows[candidate] = swapped;
1436
+ sign = -sign;
1437
+ }
1438
+ for (let i = k + 1; i < n; i++) {
1439
+ for (let j = k + 1; j < n; j++) {
1440
+ rows[i][j] = (rows[i][j] * rows[k][k] - rows[i][k] * rows[k][j]) / previous;
1441
+ }
1442
+ }
1443
+ previous = rows[k][k];
1444
+ }
1445
+ return sign * rows[n - 1][n - 1];
1446
+ }
1329
1447
  function numericDeterminant(m) {
1448
+ const integers = toIntegerRows(m);
1449
+ if (integers !== null) return numberValue(Number(integerDeterminant(integers)));
1330
1450
  const n = m.rows;
1331
1451
  const a = toWorkingRows(m);
1332
1452
  let det = 1;
@@ -1445,17 +1565,17 @@ function symbolicInverse(m) {
1445
1565
  `Symbolic inverse: the pivot at row/col ${col} is exactly zero \u2014 this matrix's structure isn't invertible via this engine's diagonal-first symbolic elimination (no row-swapping); try reordering rows manually.`
1446
1566
  );
1447
1567
  }
1448
- for (let c = 0; c < 2 * n; c++) {
1449
- a[col][c] = simplifySymbolic({ kind: "div", left: a[col][c], right: pivot });
1450
- }
1451
1568
  for (let r = 0; r < n; r++) {
1452
1569
  if (r === col) continue;
1453
- const factor = simplifySymbolic(a[r][col]);
1570
+ const factor = simplifySymbolic({ kind: "div", left: a[r][col], right: pivot });
1454
1571
  if (factor.kind === "const" && isRationalZero(factor.value)) continue;
1455
1572
  for (let c = 0; c < 2 * n; c++) {
1456
1573
  a[r][c] = simplifySymbolic({ kind: "sub", left: a[r][c], right: { kind: "mul", left: factor, right: a[col][c] } });
1457
1574
  }
1458
1575
  }
1576
+ for (let c = 0; c < 2 * n; c++) {
1577
+ a[col][c] = simplifySymbolic({ kind: "div", left: a[col][c], right: pivot });
1578
+ }
1459
1579
  }
1460
1580
  const data = new Array(n * n);
1461
1581
  for (let r = 0; r < n; r++) {
@@ -1469,16 +1589,26 @@ function inverse(m) {
1469
1589
  }
1470
1590
  return m.hasSymbolic ? symbolicInverse(m) : numericInverse(m);
1471
1591
  }
1472
- function collectionToValues(v) {
1473
- if (v.type === 13 /* Error */) return v;
1592
+ function tooLarge(length, maxElements) {
1593
+ return errorValue(
1594
+ "COLLECTION_TOO_LARGE",
1595
+ `This collection has ${length} elements, past the limit of ${maxElements} (see the engine's vm.maxCollectionSize setting).`
1596
+ );
1597
+ }
1598
+ function collectionToValues(v, maxElements = Number.POSITIVE_INFINITY) {
1599
+ const faulted = faultedOperand(v);
1600
+ if (faulted) return faulted;
1474
1601
  if (v.type === 7 /* Matrix */) {
1475
1602
  const m = v.value;
1603
+ if (m.data.length > maxElements) return tooLarge(m.data.length, maxElements);
1476
1604
  return m.data.map(matrixEntryToValue);
1477
1605
  }
1478
1606
  if (v.type === 8 /* Range */) {
1479
1607
  const r = v.value;
1480
- const out = [];
1481
- for (let i = r.min; i <= r.max; i++) out.push(numberValue(i));
1608
+ const length = r.max - r.min + 1;
1609
+ if (length > maxElements) return tooLarge(length, maxElements);
1610
+ const out = new Array(length);
1611
+ for (let i = 0; i < length; i++) out[i] = numberValue(r.min + i);
1482
1612
  return out;
1483
1613
  }
1484
1614
  return errorValue(
@@ -1595,6 +1725,6 @@ var CURRENCY_DISPLAY = {
1595
1725
  CZK: { symbol: "K\u010D", position: "suffix", spaced: true }
1596
1726
  };
1597
1727
 
1598
- export { COMPLEX_I, CURRENCY_DISPLAY, RATIONAL_ONE, RATIONAL_ZERO, callNode, cancelSymbolic, coefficientGcd, collectionToValues, columnMajorToRowMajor, compareMonomials, complex, complexNode, constNode, determinant, exactIntegerCbrt, exactIntegerSqrt, exactRationalSqrt2 as exactRationalSqrt, expandSymbolic, formatSymbolic, freeVariables, fromPolynomial, inBounds, inverse, isRationalOne, isRationalZero, isZeroPolynomial, matAt, matIndex, matrixCompare, matrixEntryToValue, matrixMultiply, monomialFromKey, monomialToKey, polyCoefficients, polyDegree, polyUnivariateVar, polynomialDivide, powNode, rationalAdd, rationalCompare, rationalDiv, rationalFromNumber, rationalMul, rationalNeg, rationalSub, rationalToNumber, resolveCurrencyAlias, rowMajorToColumnMajor, sameShape, signedSurdNode, simplifySymbolic, substitute, surdNode, symbolicKey, symbolicToEntry, toPolynomial, transpose, varNode };
1599
- //# sourceMappingURL=chunk-CYFK5SY2.js.map
1600
- //# sourceMappingURL=chunk-CYFK5SY2.js.map
1728
+ export { COMPLEX_I, CURRENCY_DISPLAY, RATIONAL_ONE, RATIONAL_ZERO, callNode, cancelSymbolic, coefficientGcd, collectionToValues, columnMajorToRowMajor, compareMonomials, complex, complexNode, constNode, determinant, exactIntegerCbrt, exactIntegerSqrt, exactRationalSqrt2 as exactRationalSqrt, expandSymbolic, formatSymbolic, freeVariables, fromPolynomial, inBounds, inverse, isRationalOne, isRationalZero, isZeroPolynomial, matAt, matIndex, matrixCompare, matrixEntryToValue, matrixMultiply, matrixPower, monomialFromKey, monomialToKey, polyCoefficients, polyDegree, polyUnivariateVar, polynomialDivide, powNode, rationalAdd, rationalCompare, rationalDiv, rationalFromNumber, rationalMul, rationalNeg, rationalSub, rationalToNumber, resolveCurrencyAlias, rowMajorToColumnMajor, sameShape, signedSurdNode, simplifySymbolic, squareFreePart, substitute, surdNode, symbolicKey, symbolicToEntry, toPolynomial, transpose, varNode };
1729
+ //# sourceMappingURL=chunk-O3ANBHSA.js.map
1730
+ //# sourceMappingURL=chunk-O3ANBHSA.js.map