@cortex-js/compute-engine 0.19.1 → 0.20.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 (101) hide show
  1. package/dist/compute-engine.esm.js +1024 -355
  2. package/dist/compute-engine.js +1024 -355
  3. package/dist/compute-engine.min.esm.js +10 -9
  4. package/dist/compute-engine.min.js +10 -9
  5. package/dist/math-json.esm.js +2 -2
  6. package/dist/math-json.js +2 -2
  7. package/dist/math-json.min.esm.js +2 -2
  8. package/dist/math-json.min.js +2 -2
  9. package/dist/types/common/ansi-codes.d.ts +1 -1
  10. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  11. package/dist/types/common/signals.d.ts +4 -4
  12. package/dist/types/common/utils.d.ts +1 -1
  13. package/dist/types/compute-engine/assume.d.ts +1 -1
  14. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +1 -1
  15. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  16. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  17. package/dist/types/compute-engine/boxed-expression/boxed-domain.d.ts +1 -1
  18. package/dist/types/compute-engine/boxed-expression/boxed-function-definition.d.ts +1 -1
  19. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
  20. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
  21. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  22. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  23. package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +1 -1
  24. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
  25. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  26. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  27. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  28. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -3
  29. package/dist/types/compute-engine/boxed-expression/validate.d.ts +7 -3
  30. package/dist/types/compute-engine/collection-utils.d.ts +1 -1
  31. package/dist/types/compute-engine/compile.d.ts +1 -1
  32. package/dist/types/compute-engine/compute-engine.d.ts +1 -1
  33. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  34. package/dist/types/compute-engine/domain-utils.d.ts +1 -1
  35. package/dist/types/compute-engine/function-utils.d.ts +1 -1
  36. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  37. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  38. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  39. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  40. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +25 -1
  41. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-inequalities.d.ts +1 -1
  42. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  43. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  44. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  45. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  46. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  47. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  48. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
  49. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
  50. package/dist/types/compute-engine/latex-syntax/parse-identifier.d.ts +1 -1
  51. package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -23
  52. package/dist/types/compute-engine/latex-syntax/public.d.ts +11 -24
  53. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
  54. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  55. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
  56. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  57. package/dist/types/compute-engine/library/arithmetic-add.d.ts +1 -1
  58. package/dist/types/compute-engine/library/arithmetic-divide.d.ts +1 -1
  59. package/dist/types/compute-engine/library/arithmetic-multiply.d.ts +1 -1
  60. package/dist/types/compute-engine/library/arithmetic-power.d.ts +1 -1
  61. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  62. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  63. package/dist/types/compute-engine/library/collections.d.ts +1 -1
  64. package/dist/types/compute-engine/library/complex.d.ts +1 -1
  65. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  66. package/dist/types/compute-engine/library/core.d.ts +1 -1
  67. package/dist/types/compute-engine/library/domains.d.ts +1 -1
  68. package/dist/types/compute-engine/library/library.d.ts +1 -1
  69. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  70. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  71. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  72. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  73. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  74. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  75. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  76. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  77. package/dist/types/compute-engine/library/utils.d.ts +1 -1
  78. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  79. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  80. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  81. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  82. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  83. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  84. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  85. package/dist/types/compute-engine/public.d.ts +1 -1
  86. package/dist/types/compute-engine/rules.d.ts +1 -1
  87. package/dist/types/compute-engine/simplify-rules.d.ts +1 -1
  88. package/dist/types/compute-engine/solve.d.ts +1 -1
  89. package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
  90. package/dist/types/compute-engine/symbolic/expand.d.ts +1 -1
  91. package/dist/types/compute-engine/symbolic/flatten.d.ts +1 -3
  92. package/dist/types/compute-engine/symbolic/negate.d.ts +1 -1
  93. package/dist/types/compute-engine/symbolic/polynomials.d.ts +1 -1
  94. package/dist/types/compute-engine/symbolic/product.d.ts +1 -1
  95. package/dist/types/compute-engine/symbolic/sum.d.ts +1 -1
  96. package/dist/types/compute-engine/symbolic/utils.d.ts +1 -1
  97. package/dist/types/compute-engine.d.ts +2 -2
  98. package/dist/types/math-json/math-json-format.d.ts +1 -1
  99. package/dist/types/math-json/utils.d.ts +1 -4
  100. package/dist/types/math-json.d.ts +2 -2
  101. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- /** CortexJS Compute Engine 0.19.1 */
1
+ /** CortexJS Compute Engine 0.20.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.ComputeEngine = {}));})(this, (function (exports) { 'use strict';
3
3
  var ComputeEngine = (() => {
4
4
  var __create = Object.create;
@@ -3994,14 +3994,6 @@ var ComputeEngine = (() => {
3994
3994
  return null;
3995
3995
  return s;
3996
3996
  }
3997
- function isListLike(expr) {
3998
- if (expr === null)
3999
- return false;
4000
- const h = head(expr);
4001
- if (!h || typeof h !== "string")
4002
- return false;
4003
- return /^(List|Sequence|Tuple|Single|Pair|Triple)$/.test(h);
4004
- }
4005
3997
  function keyValuePair(expr) {
4006
3998
  const h = head(expr);
4007
3999
  if (h === "KeyValuePair" || h === "Tuple" || h === "Pair") {
@@ -4161,21 +4153,21 @@ var ComputeEngine = (() => {
4161
4153
  expr = op(expr, 1);
4162
4154
  if (expr === null)
4163
4155
  return [];
4164
- if (head(expr) !== "Sequence")
4156
+ h = head(expr);
4157
+ if (h !== "Sequence")
4165
4158
  return [expr];
4166
4159
  }
4167
- h = head(expr);
4168
4160
  if (h !== "Sequence")
4169
4161
  return null;
4170
4162
  return ops(expr) ?? [];
4171
4163
  }
4172
4164
  function isEmptySequence(expr) {
4173
- return expr !== null && head(expr) === "Sequence" && nops(expr) === 0;
4165
+ return head(expr) === "Sequence" && nops(expr) === 0;
4174
4166
  }
4175
4167
  function missingIfEmpty(expr) {
4176
- if (expr === null || isEmptySequence(expr))
4168
+ if (isEmptySequence(expr))
4177
4169
  return MISSING;
4178
- return expr;
4170
+ return expr ?? MISSING;
4179
4171
  }
4180
4172
  function countFunctionLeaves(xs) {
4181
4173
  if (xs[0] === "Square") {
@@ -4345,9 +4337,9 @@ var ComputeEngine = (() => {
4345
4337
  if (val < 0) {
4346
4338
  result += serializer.serialize(arg);
4347
4339
  } else if (head(arg) === "Negate") {
4348
- result += serializer.wrap(arg, 275);
4340
+ result += serializer.wrap(arg, ADDITION_PRECEDENCE);
4349
4341
  } else {
4350
- const term = serializer.wrap(arg, 275);
4342
+ const term = serializer.wrap(arg, ADDITION_PRECEDENCE);
4351
4343
  if (term[0] === "-" || term[0] === "+")
4352
4344
  result += term;
4353
4345
  else
@@ -4355,10 +4347,10 @@ var ComputeEngine = (() => {
4355
4347
  }
4356
4348
  }
4357
4349
  } else if (name === "Subtract") {
4358
- result = serializer.wrap(arg, 275);
4350
+ result = serializer.wrap(arg, ADDITION_PRECEDENCE);
4359
4351
  const arg2 = op(expr, 2);
4360
4352
  if (arg2 !== null) {
4361
- const term = serializer.wrap(arg2, 275);
4353
+ const term = serializer.wrap(arg2, ADDITION_PRECEDENCE);
4362
4354
  if (term[0] === "-")
4363
4355
  result += "+" + term.slice(1);
4364
4356
  else if (term[0] === "+")
@@ -4448,7 +4440,7 @@ var ComputeEngine = (() => {
4448
4440
  arg = op(arg, 1);
4449
4441
  isNegative = !isNegative;
4450
4442
  }
4451
- term = serializer.wrap(arg, 390);
4443
+ term = serializer.wrap(arg, MULTIPLICATION_PRECEDENCE);
4452
4444
  if (!result) {
4453
4445
  result = term;
4454
4446
  } else {
@@ -4697,11 +4689,14 @@ var ComputeEngine = (() => {
4697
4689
  latexTrigger: ["+"],
4698
4690
  kind: "infix",
4699
4691
  associativity: "both",
4700
- precedence: 275,
4692
+ precedence: ADDITION_PRECEDENCE,
4701
4693
  parse: (parser, lhs, until) => {
4702
- if (until && 275 < until.minPrec)
4694
+ if (until && ADDITION_PRECEDENCE < until.minPrec)
4703
4695
  return null;
4704
- const rhs = parser.parseExpression({ ...until, minPrec: 275 });
4696
+ const rhs = parser.parseExpression({
4697
+ ...until,
4698
+ minPrec: ADDITION_PRECEDENCE
4699
+ });
4705
4700
  if (rhs === null)
4706
4701
  return null;
4707
4702
  return applyAssociativeOperator("Add", lhs, rhs);
@@ -4711,9 +4706,9 @@ var ComputeEngine = (() => {
4711
4706
  {
4712
4707
  kind: "prefix",
4713
4708
  latexTrigger: ["+"],
4714
- precedence: 275,
4709
+ precedence: ADDITION_PRECEDENCE,
4715
4710
  parse: (parser, until) => {
4716
- if (until && 275 < until.minPrec)
4711
+ if (until && ADDITION_PRECEDENCE < until.minPrec)
4717
4712
  return null;
4718
4713
  return parser.parseExpression({ ...until, minPrec: 400 });
4719
4714
  }
@@ -4741,7 +4736,7 @@ var ComputeEngine = (() => {
4741
4736
  { name: "Chop", identifierTrigger: "chop", kind: "function", parse: "Chop" },
4742
4737
  {
4743
4738
  name: "Complex",
4744
- precedence: 274,
4739
+ precedence: ADDITION_PRECEDENCE - 1,
4745
4740
  // One less than precedence of `Add`: used for correct wrapping
4746
4741
  serialize: (serializer, expr) => {
4747
4742
  const re = machineValue(op(expr, 1));
@@ -4759,7 +4754,7 @@ var ComputeEngine = (() => {
4759
4754
  {
4760
4755
  name: "Divide",
4761
4756
  latexTrigger: "\\frac",
4762
- precedence: 660,
4757
+ precedence: DIVISION_PRECEDENCE,
4763
4758
  // For \frac specifically, not for \div, etc..
4764
4759
  // handles Leibnitz notation for partial derivatives
4765
4760
  parse: parseFraction,
@@ -4768,14 +4763,14 @@ var ComputeEngine = (() => {
4768
4763
  {
4769
4764
  kind: "infix",
4770
4765
  latexTrigger: "\\over",
4771
- precedence: 660,
4766
+ precedence: DIVISION_PRECEDENCE,
4772
4767
  parse: "Divide"
4773
4768
  },
4774
4769
  {
4775
4770
  latexTrigger: ["\\/"],
4776
4771
  kind: "infix",
4777
4772
  associativity: "non",
4778
- precedence: 660,
4773
+ precedence: DIVISION_PRECEDENCE,
4779
4774
  // ??? MathML has 265, but it's wrong.
4780
4775
  // It has to be at least higher than multiply
4781
4776
  // e.g. `1/2+3*x` -> `1/2 + 3*x` , not `1/(2+3*x)`
@@ -4785,14 +4780,14 @@ var ComputeEngine = (() => {
4785
4780
  latexTrigger: ["/"],
4786
4781
  kind: "infix",
4787
4782
  associativity: "non",
4788
- precedence: 660,
4783
+ precedence: DIVISION_PRECEDENCE,
4789
4784
  parse: "Divide"
4790
4785
  },
4791
4786
  {
4792
4787
  latexTrigger: ["\\div"],
4793
4788
  kind: "infix",
4794
4789
  associativity: "non",
4795
- precedence: 660,
4790
+ precedence: DIVISION_PRECEDENCE,
4796
4791
  // ??? according to MathML
4797
4792
  parse: "Divide"
4798
4793
  },
@@ -4809,13 +4804,13 @@ var ComputeEngine = (() => {
4809
4804
  name: "Factorial",
4810
4805
  latexTrigger: ["!"],
4811
4806
  kind: "postfix",
4812
- precedence: 810
4807
+ precedence: POSTFIX_PRECEDENCE
4813
4808
  },
4814
4809
  {
4815
4810
  name: "Factorial2",
4816
4811
  latexTrigger: ["!", "!"],
4817
4812
  kind: "postfix",
4818
- precedence: 810
4813
+ precedence: POSTFIX_PRECEDENCE
4819
4814
  },
4820
4815
  {
4821
4816
  name: "Floor",
@@ -4948,23 +4943,26 @@ var ComputeEngine = (() => {
4948
4943
  latexTrigger: ["\\mp"],
4949
4944
  kind: "infix",
4950
4945
  associativity: "both",
4951
- precedence: 270
4946
+ precedence: ARROW_PRECEDENCE
4952
4947
  },
4953
4948
  {
4954
4949
  name: "Multiply",
4955
4950
  latexTrigger: ["\\times"],
4956
4951
  kind: "infix",
4957
4952
  associativity: "both",
4958
- precedence: 390,
4953
+ precedence: MULTIPLICATION_PRECEDENCE,
4959
4954
  serialize: serializeMultiply
4960
4955
  },
4961
4956
  {
4962
4957
  latexTrigger: ["\\cdot"],
4963
4958
  kind: "infix",
4964
4959
  associativity: "both",
4965
- precedence: 390,
4960
+ precedence: MULTIPLICATION_PRECEDENCE,
4966
4961
  parse: (parser, lhs, terminator) => {
4967
- const rhs = parser.parseExpression({ ...terminator, minPrec: 392 });
4962
+ const rhs = parser.parseExpression({
4963
+ ...terminator,
4964
+ minPrec: MULTIPLICATION_PRECEDENCE + 2
4965
+ });
4968
4966
  if (rhs === null)
4969
4967
  return ["Multiply", lhs, MISSING];
4970
4968
  return applyAssociativeOperator("Multiply", lhs, rhs);
@@ -4974,23 +4972,77 @@ var ComputeEngine = (() => {
4974
4972
  latexTrigger: ["*"],
4975
4973
  kind: "infix",
4976
4974
  associativity: "both",
4977
- precedence: 390,
4975
+ precedence: MULTIPLICATION_PRECEDENCE,
4978
4976
  parse: (parser, lhs, terminator) => {
4979
- const rhs = parser.parseExpression({ ...terminator, minPrec: 392 });
4977
+ const rhs = parser.parseExpression({
4978
+ ...terminator,
4979
+ minPrec: MULTIPLICATION_PRECEDENCE + 2
4980
+ });
4980
4981
  if (rhs === null)
4981
4982
  return ["Multiply", lhs, MISSING];
4982
4983
  return applyAssociativeOperator("Multiply", lhs, rhs);
4983
4984
  }
4984
4985
  },
4986
+ // Infix modulo, as in `26 \bmod 5`
4987
+ {
4988
+ name: "Mod",
4989
+ latexTrigger: "\\bmod",
4990
+ kind: "infix",
4991
+ precedence: DIVISION_PRECEDENCE,
4992
+ serialize: (serializer, expr) => {
4993
+ if (nops(expr) !== 2)
4994
+ return "";
4995
+ const lhs = serializer.serialize(op(expr, 1));
4996
+ const rhs = serializer.serialize(op(expr, 2));
4997
+ return joinLatex([lhs, "\\bmod", rhs]);
4998
+ }
4999
+ },
5000
+ // Synonym to \\bmod
5001
+ {
5002
+ latexTrigger: "\\mod",
5003
+ kind: "infix",
5004
+ precedence: DIVISION_PRECEDENCE,
5005
+ parse: "Mod"
5006
+ },
5007
+ {
5008
+ latexTrigger: "\\pmod",
5009
+ kind: "prefix",
5010
+ precedence: COMPARISON_PRECEDENCE,
5011
+ parse: (parser) => {
5012
+ const rhs = parser.parseGroup() ?? parser.parseToken();
5013
+ return ["Mod", missingIfEmpty(rhs)];
5014
+ }
5015
+ },
5016
+ {
5017
+ name: "Congruent",
5018
+ serialize: (serializer, expr) => {
5019
+ const lhs = serializer.serialize(op(expr, 1));
5020
+ const rhs = serializer.serialize(op(expr, 2));
5021
+ if (op(expr, 3) === null)
5022
+ return joinLatex([lhs, "\\equiv", rhs]);
5023
+ const modulus = serializer.serialize(op(expr, 3));
5024
+ return joinLatex([lhs, "\\equiv", rhs, "\\pmod{", modulus, "}"]);
5025
+ }
5026
+ },
4985
5027
  {
4986
5028
  name: "Negate",
4987
5029
  latexTrigger: ["-"],
4988
5030
  kind: "prefix",
5031
+ precedence: ADDITION_PRECEDENCE,
4989
5032
  parse: (parser, terminator) => {
4990
- const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
5033
+ if (/\d/.test(parser.peek))
5034
+ return null;
5035
+ const index = parser.index;
5036
+ if (parser.parseNumber() !== null) {
5037
+ parser.index = index;
5038
+ return null;
5039
+ }
5040
+ const rhs = parser.parseExpression({
5041
+ ...terminator,
5042
+ minPrec: ADDITION_PRECEDENCE + 1
5043
+ });
4991
5044
  return ["Negate", missingIfEmpty(rhs)];
4992
- },
4993
- precedence: 275
5045
+ }
4994
5046
  },
4995
5047
  // {
4996
5048
  // /** If the argument is a vector */
@@ -5030,7 +5082,7 @@ var ComputeEngine = (() => {
5030
5082
  latexTrigger: ["\\pm"],
5031
5083
  kind: "infix",
5032
5084
  associativity: "both",
5033
- precedence: 270,
5085
+ precedence: ARROW_PRECEDENCE,
5034
5086
  serialize: (serializer, expr) => {
5035
5087
  const op12 = op(expr, 1);
5036
5088
  if (op12 === null)
@@ -5048,7 +5100,7 @@ var ComputeEngine = (() => {
5048
5100
  {
5049
5101
  latexTrigger: ["\\pm"],
5050
5102
  kind: "prefix",
5051
- precedence: 270,
5103
+ precedence: ARROW_PRECEDENCE,
5052
5104
  parse: (parser, terminator) => {
5053
5105
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
5054
5106
  return ["PlusMinus", missingIfEmpty(rhs)];
@@ -5058,7 +5110,7 @@ var ComputeEngine = (() => {
5058
5110
  latexTrigger: ["\\plusmn"],
5059
5111
  kind: "infix",
5060
5112
  associativity: "both",
5061
- precedence: 270,
5113
+ precedence: ARROW_PRECEDENCE,
5062
5114
  parse: (parser, lhs, terminator) => {
5063
5115
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
5064
5116
  return ["PlusMinus", lhs, missingIfEmpty(rhs)];
@@ -5067,7 +5119,7 @@ var ComputeEngine = (() => {
5067
5119
  {
5068
5120
  latexTrigger: ["\\plusmn"],
5069
5121
  kind: "prefix",
5070
- precedence: 270,
5122
+ precedence: ARROW_PRECEDENCE,
5071
5123
  parse: (parser, terminator) => {
5072
5124
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
5073
5125
  return ["PlusMinus", missingIfEmpty(rhs)];
@@ -5082,9 +5134,9 @@ var ComputeEngine = (() => {
5082
5134
  },
5083
5135
  {
5084
5136
  latexTrigger: "\\prod",
5085
- precedence: 390,
5137
+ precedence: MULTIPLICATION_PRECEDENCE,
5086
5138
  name: "Product",
5087
- parse: parseBigOp("Product", 390),
5139
+ parse: parseBigOp("Product", MULTIPLICATION_PRECEDENCE),
5088
5140
  serialize: serializeBigOp("\\prod")
5089
5141
  },
5090
5142
  // {
@@ -5095,7 +5147,7 @@ var ComputeEngine = (() => {
5095
5147
  // },
5096
5148
  {
5097
5149
  name: "Rational",
5098
- precedence: 660,
5150
+ precedence: DIVISION_PRECEDENCE,
5099
5151
  serialize: (serializer, expr) => {
5100
5152
  if (expr && nops(expr) === 1)
5101
5153
  return "\\operatorname{Rational}" + serializer.wrapArguments(expr);
@@ -5118,9 +5170,9 @@ var ComputeEngine = (() => {
5118
5170
  },
5119
5171
  {
5120
5172
  latexTrigger: ["\\sum"],
5121
- precedence: 275,
5173
+ precedence: ADDITION_PRECEDENCE,
5122
5174
  name: "Sum",
5123
- parse: parseBigOp("Sum", 275),
5175
+ parse: parseBigOp("Sum", ADDITION_PRECEDENCE),
5124
5176
  serialize: serializeBigOp("\\sum")
5125
5177
  },
5126
5178
  {
@@ -5140,9 +5192,12 @@ var ComputeEngine = (() => {
5140
5192
  latexTrigger: ["-"],
5141
5193
  kind: "infix",
5142
5194
  associativity: "both",
5143
- precedence: 275,
5195
+ precedence: ADDITION_PRECEDENCE,
5144
5196
  parse: (parser, lhs, terminator) => {
5145
- const rhs = parser.parseExpression({ ...terminator, minPrec: 277 });
5197
+ const rhs = parser.parseExpression({
5198
+ ...terminator,
5199
+ minPrec: ADDITION_PRECEDENCE + 2
5200
+ });
5146
5201
  return ["Subtract", lhs, missingIfEmpty(rhs)];
5147
5202
  }
5148
5203
  }
@@ -5243,10 +5298,9 @@ var ComputeEngine = (() => {
5243
5298
 
5244
5299
  // src/compute-engine/latex-syntax/dictionary/definitions-core.ts
5245
5300
  function parseSequence(parser, terminator, lhs, prec, sep) {
5246
- console.assert(lhs !== null);
5247
5301
  if (terminator.minPrec >= prec)
5248
5302
  return null;
5249
- const result = [lhs];
5303
+ const result = lhs ? [lhs] : ["Nothing"];
5250
5304
  let done = false;
5251
5305
  while (!done) {
5252
5306
  done = true;
@@ -5270,7 +5324,40 @@ var ComputeEngine = (() => {
5270
5324
  return result;
5271
5325
  }
5272
5326
  function serializeOps(sep = "") {
5273
- return (serializer, expr) => (ops(expr) ?? []).map((x) => serializer.serialize(x)).join(sep);
5327
+ return (serializer, expr) => {
5328
+ if (!expr)
5329
+ return "";
5330
+ const xs = ops(expr) ?? [];
5331
+ if (xs.length === 0)
5332
+ return "";
5333
+ if (xs.length === 1)
5334
+ return serializer.serialize(xs[0]);
5335
+ sep = {
5336
+ "&": "\\&",
5337
+ ":": "\\colon",
5338
+ "|": "\\mvert",
5339
+ "-": "-",
5340
+ "\xB7": "\\cdot",
5341
+ // U+00B7 MIDDLE DOT
5342
+ "\u2012": "-",
5343
+ // U+2012 FIGURE DASH
5344
+ "\u2013": "--",
5345
+ // U+2013 EN DASH
5346
+ "\u2014": "---",
5347
+ // U+2014 EM DASH
5348
+ "\u2015": "-",
5349
+ // U+2015 HORIZONTAL BAR
5350
+ "\u2022": "\\bullet",
5351
+ // U+2022 BULLET
5352
+ "\u2026": "\\ldots"
5353
+ }[sep] ?? sep;
5354
+ const ys = xs.reduce((acc, item) => {
5355
+ acc.push(serializer.serialize(item), sep);
5356
+ return acc;
5357
+ }, []);
5358
+ ys.pop();
5359
+ return joinLatex(ys);
5360
+ };
5274
5361
  }
5275
5362
  var DEFINITIONS_CORE = [
5276
5363
  //
@@ -5301,7 +5388,7 @@ var ComputeEngine = (() => {
5301
5388
  name: "Function",
5302
5389
  latexTrigger: ["\\mapsto"],
5303
5390
  kind: "infix",
5304
- precedence: 270,
5391
+ precedence: ARROW_PRECEDENCE,
5305
5392
  // MathML rightwards arrow
5306
5393
  parse: (parser, lhs) => {
5307
5394
  let params = [];
@@ -5320,7 +5407,7 @@ var ComputeEngine = (() => {
5320
5407
  else
5321
5408
  return null;
5322
5409
  }
5323
- let rhs = parser.parseExpression({ minPrec: 270 }) ?? "Nothing";
5410
+ let rhs = parser.parseExpression({ minPrec: ARROW_PRECEDENCE }) ?? "Nothing";
5324
5411
  if (head(rhs) === "Delimiter")
5325
5412
  rhs = op(rhs, 1) ?? "Nothing";
5326
5413
  if (head(rhs) === "Sequence")
@@ -5378,12 +5465,14 @@ var ComputeEngine = (() => {
5378
5465
  return ["Apply", rhs, lhs];
5379
5466
  }
5380
5467
  },
5468
+ // The mathtools package includes several synonmyms for \colonequals. The
5469
+ // current preferred one is `\coloneq`
5381
5470
  {
5382
5471
  name: "Assign",
5383
- latexTrigger: "\\coloneqq",
5472
+ latexTrigger: "\\coloneq",
5384
5473
  kind: "infix",
5385
5474
  associativity: "right",
5386
- precedence: 260,
5475
+ precedence: ASSIGNMENT_PRECEDENCE,
5387
5476
  // parse: (parser: Parser, lhs: Expression) => {
5388
5477
  // const rhs = parser.parseExpression({ minPrec: 260 }) ?? 'Nothing';
5389
5478
  // return ['Assign', lhs, rhs];
@@ -5391,37 +5480,32 @@ var ComputeEngine = (() => {
5391
5480
  serialize: (serializer, expr) => {
5392
5481
  return joinLatex([
5393
5482
  serializer.serialize(op(expr, 1)),
5394
- "\\coloneqq",
5483
+ "\\coloneq",
5395
5484
  serializer.serialize(op(expr, 2))
5396
5485
  ]);
5397
- }
5486
+ },
5487
+ parse: parseAssign
5398
5488
  },
5399
5489
  {
5400
5490
  latexTrigger: [":", "="],
5401
5491
  kind: "infix",
5402
5492
  associativity: "right",
5403
- precedence: 260,
5404
- parse: "Assign"
5493
+ precedence: ASSIGNMENT_PRECEDENCE,
5494
+ parse: parseAssign
5405
5495
  },
5406
- // {
5407
- // kind: 'function',
5408
- // latexTrigger: ':=', // \coloneqq
5409
- // parse: (parser: Parser, lhs: Expression) => {
5410
- // const rhs = parser.parseExpression({ minPrec: 270 }) ?? 'Nothing';
5411
- // return ['Assign', lhs, rhs];
5412
- // },
5413
- // },
5414
5496
  {
5415
5497
  latexTrigger: "\\colonequals",
5416
- // \coloneqq
5417
5498
  kind: "infix",
5418
5499
  associativity: "right",
5419
- precedence: 260,
5420
- parse: "Assign"
5421
- // parse: (parser: Parser, lhs: Expression) => {
5422
- // const rhs = parser.parseExpression({ minPrec: 270 }) ?? 'Nothing';
5423
- // return ['Assign', lhs, rhs];
5424
- // },
5500
+ precedence: ASSIGNMENT_PRECEDENCE,
5501
+ parse: parseAssign
5502
+ },
5503
+ {
5504
+ latexTrigger: "\\coloneqq",
5505
+ kind: "infix",
5506
+ associativity: "right",
5507
+ precedence: ASSIGNMENT_PRECEDENCE,
5508
+ parse: parseAssign
5425
5509
  },
5426
5510
  {
5427
5511
  name: "BaseForm",
@@ -5457,28 +5541,151 @@ var ComputeEngine = (() => {
5457
5541
  }
5458
5542
  },
5459
5543
  {
5544
+ name: "Sequence",
5545
+ // Use a space as a separator, otherwise a sequence of numbers
5546
+ // could be interpreted as a single number.
5547
+ serialize: serializeOps(" ")
5548
+ },
5549
+ {
5550
+ name: "InvisibleOperator",
5551
+ serialize: serializeOps("")
5552
+ },
5553
+ {
5554
+ // The first argument is a function expression.
5555
+ // The second (optional) argument is a string specifying the
5556
+ // delimiters and separator.
5460
5557
  name: "Delimiter",
5461
5558
  serialize: (serializer, expr) => {
5462
- const argCount = nops(expr);
5463
- if (argCount === 0)
5464
- return "";
5465
- const style = serializer.options.groupStyle(expr, serializer.level + 1);
5466
5559
  const arg1 = op(expr, 1);
5560
+ const style = serializer.options.groupStyle(expr, serializer.level + 1);
5467
5561
  const h1 = head(arg1);
5468
- const defaultFence = { List: "[],", Sequence: "" }[typeof h1 === "string" ? h1 : ""] ?? "(),";
5469
- let open = defaultFence[0] ?? "";
5470
- let close = defaultFence[1] ?? "";
5471
- let sep = defaultFence[2] ?? "";
5472
- if (argCount > 1) {
5473
- const op22 = stringValue(op(expr, 2)) ?? "";
5474
- open = op22[0] ?? defaultFence[0];
5475
- close = op22[1] ?? defaultFence[1];
5476
- sep = op22[2] ?? defaultFence[2];
5477
- }
5478
- const body = isListLike(arg1) ? serializeOps(sep)(serializer, arg1) : serializer.serialize(arg1);
5562
+ let delims = {
5563
+ Set: "{,}",
5564
+ List: "[,]",
5565
+ Tuple: "(,)",
5566
+ Single: "(,)",
5567
+ Pair: "(,)",
5568
+ Triple: "(,)",
5569
+ Sequence: "(,)",
5570
+ String: '""'
5571
+ }[typeof h1 === "string" ? h1 : ""] ?? "(,)";
5572
+ if (nops(expr) > 1) {
5573
+ const op22 = stringValue(op(expr, 2));
5574
+ if (typeof op22 === "string" && op22.length <= 3)
5575
+ delims = op22;
5576
+ }
5577
+ let [open, sep, close] = ["", "", ""];
5578
+ if (delims.length === 3)
5579
+ [open, sep, close] = delims;
5580
+ else if (delims.length === 2)
5581
+ [open, close] = delims;
5582
+ else if (delims.length === 1)
5583
+ sep = delims;
5584
+ const body = arg1 ? ops(arg1) ? serializeOps(sep)(serializer, arg1) : serializer.serialize(arg1) : "";
5479
5585
  return serializer.wrapString(body, style, open + close);
5480
5586
  }
5481
5587
  },
5588
+ // The first argument is the matrix data.
5589
+ // The second, optional, argument are the delimiters.
5590
+ // The third, optional, argument is the column specification.
5591
+ {
5592
+ name: "Matrix",
5593
+ // https://ctan.math.illinois.edu/macros/latex/required/tools/array.pdf
5594
+ serialize: (serializer, expr) => {
5595
+ const body = op(expr, 1);
5596
+ const delims = op(expr, 2) ?? "()";
5597
+ let columns = "";
5598
+ if (op(expr, 3) !== null) {
5599
+ const colsSpec = stringValue(op(expr, 3)) ?? "";
5600
+ for (const c of colsSpec) {
5601
+ if (c === "<")
5602
+ columns += "l";
5603
+ else if (c === ">")
5604
+ columns += "r";
5605
+ else if (c === "=")
5606
+ columns += "c";
5607
+ else if (c === "|")
5608
+ columns += "|";
5609
+ else if (c === ":")
5610
+ columns += ":";
5611
+ }
5612
+ }
5613
+ let [open, close] = ["", ""];
5614
+ if (typeof delims === "string" && delims.length === 2)
5615
+ [open, close] = delims;
5616
+ const rows = [];
5617
+ for (const row of ops(body) ?? []) {
5618
+ const cells = [];
5619
+ for (const cell of ops(row) ?? [])
5620
+ cells.push(serializer.serialize(cell));
5621
+ rows.push(cells.join(" & "));
5622
+ }
5623
+ const tabular = rows.join("\\\\\n");
5624
+ const optColumns = columns.length > 0 ? `[${columns}]` : "";
5625
+ if (open === "(" && close === ")")
5626
+ return joinLatex([
5627
+ "\\begin{pmatrix}",
5628
+ optColumns,
5629
+ tabular,
5630
+ "\\end{pmatrix}"
5631
+ ]);
5632
+ if (open === "[" && close === "]")
5633
+ return joinLatex([
5634
+ "\\begin{bmatrix}",
5635
+ optColumns,
5636
+ tabular,
5637
+ "\\end{bmatrix}"
5638
+ ]);
5639
+ if (open === "{" && close === "}")
5640
+ return joinLatex([
5641
+ "\\begin{Bmatrix}",
5642
+ optColumns,
5643
+ tabular,
5644
+ "\\end{Bmatrix}"
5645
+ ]);
5646
+ if (open === "|" && close === "|")
5647
+ return joinLatex([
5648
+ "\\begin{vmatrix}",
5649
+ optColumns,
5650
+ tabular,
5651
+ "\\end{vmatrix}"
5652
+ ]);
5653
+ if (open === "\u2016" && close === "\u2016")
5654
+ return joinLatex([
5655
+ "\\begin{Vmatrix}",
5656
+ optColumns,
5657
+ tabular,
5658
+ "\\end{Vmatrix}"
5659
+ ]);
5660
+ if (open === "{" && close === ".")
5661
+ return joinLatex([
5662
+ "\\begin{dcases}",
5663
+ optColumns,
5664
+ tabular,
5665
+ "\\end{dcases}"
5666
+ ]);
5667
+ if (open === "." && close === "}")
5668
+ return joinLatex([
5669
+ "\\begin{rcases}",
5670
+ optColumns,
5671
+ tabular,
5672
+ "\\end{rcases}"
5673
+ ]);
5674
+ if (columns || open !== "." || close !== ".") {
5675
+ return joinLatex([
5676
+ "\\left",
5677
+ DELIMITERS_SHORTHAND[open] ?? open,
5678
+ "\\begin{array}",
5679
+ `{${columns}}`,
5680
+ tabular,
5681
+ "\\end{array}",
5682
+ "\\right",
5683
+ DELIMITERS_SHORTHAND[close] ?? close
5684
+ ]);
5685
+ }
5686
+ return joinLatex(["\\begin{matrix}", tabular, "\\end{matrix}"]);
5687
+ }
5688
+ },
5482
5689
  {
5483
5690
  name: "Domain",
5484
5691
  serialize: (serializer, expr) => {
@@ -5584,7 +5791,7 @@ var ComputeEngine = (() => {
5584
5791
  kind: "matchfix",
5585
5792
  openTrigger: "(",
5586
5793
  closeTrigger: ")",
5587
- parse: parseDelimiter
5794
+ parse: parseParenDelimiter
5588
5795
  },
5589
5796
  {
5590
5797
  latexTrigger: [","],
@@ -5599,7 +5806,20 @@ var ComputeEngine = (() => {
5599
5806
  const seq = parseSequence(parser, terminator, lhs, 20, ",");
5600
5807
  if (seq === null)
5601
5808
  return null;
5602
- return ["Sequence", ...seq];
5809
+ return ["Delimiter", ["Sequence", ...seq], { str: "," }];
5810
+ }
5811
+ },
5812
+ // Entry to handle the case of a single comma
5813
+ // with a missing lhs.
5814
+ {
5815
+ latexTrigger: [","],
5816
+ kind: "prefix",
5817
+ precedence: 20,
5818
+ parse: (parser, terminator) => {
5819
+ const seq = parseSequence(parser, terminator, null, 20, ",");
5820
+ if (seq === null)
5821
+ return null;
5822
+ return ["Delimiter", ["Sequence", ...seq], { str: "," }];
5603
5823
  }
5604
5824
  },
5605
5825
  {
@@ -5627,10 +5847,6 @@ var ComputeEngine = (() => {
5627
5847
  return "";
5628
5848
  }
5629
5849
  },
5630
- {
5631
- name: "Sequence",
5632
- serialize: serializeOps("")
5633
- },
5634
5850
  {
5635
5851
  latexTrigger: [";"],
5636
5852
  kind: "infix",
@@ -5639,12 +5855,7 @@ var ComputeEngine = (() => {
5639
5855
  const seq = parseSequence(parser, terminator, lhs, 19, ";");
5640
5856
  if (seq === null)
5641
5857
  return null;
5642
- return [
5643
- "Sequence",
5644
- ...seq.map(
5645
- (x) => head(x) === "Sequence" ? ["List", ...ops(x) ?? []] : x
5646
- )
5647
- ];
5858
+ return ["Delimiter", ["Sequence", ...seq], "';'"];
5648
5859
  }
5649
5860
  },
5650
5861
  {
@@ -5911,8 +6122,66 @@ var ComputeEngine = (() => {
5911
6122
  text += "$$";
5912
6123
  parser.index = index;
5913
6124
  }
5914
- } else
5915
- text += parser.matchChar() ?? parser.nextToken();
6125
+ } else {
6126
+ const c = parser.matchChar() ?? parser.nextToken();
6127
+ text += {
6128
+ "\\enskip": "\u2002",
6129
+ // en space
6130
+ "\\enspace": "\u2002",
6131
+ // en space
6132
+ "\\quad": "\u2003",
6133
+ // em space
6134
+ "\\qquad": "\u2003\u2003",
6135
+ // 2 em space
6136
+ "\\space": "\u2003",
6137
+ // em space
6138
+ "\\ ": "\u2003",
6139
+ // em space
6140
+ "\\;": "\u2004",
6141
+ // three per em space
6142
+ "\\,": "\u2009",
6143
+ // thin space
6144
+ "\\:": "\u205F",
6145
+ // medium mathematical space
6146
+ "\\!": "",
6147
+ // negative thin space
6148
+ "\\{": "{",
6149
+ "\\}": "}",
6150
+ "\\$": "$",
6151
+ "\\&": "&",
6152
+ "\\#": "#",
6153
+ "\\%": "%",
6154
+ "\\_": "_",
6155
+ "\\textbackslash": "\\",
6156
+ "\\textasciitilde": "~",
6157
+ "\\textasciicircum": "^",
6158
+ "\\textless": "<",
6159
+ "\\textgreater": ">",
6160
+ "\\textbar": "|",
6161
+ "\\textunderscore": "_",
6162
+ "\\textbraceleft": "{",
6163
+ "\\textbraceright": "}",
6164
+ "\\textasciigrave": "`",
6165
+ "\\textquotesingle": "'",
6166
+ "\\textquotedblleft": "\u201C",
6167
+ "\\textquotedblright": "\u201D",
6168
+ "\\textquotedbl": '"',
6169
+ "\\textquoteleft": "\u2018",
6170
+ "\\textquoteright": "\u2019",
6171
+ "\\textbullet": "\u2022",
6172
+ "\\textdagger": "\u2020",
6173
+ "\\textdaggerdbl": "\u2021",
6174
+ "\\textsection": "\xA7",
6175
+ "\\textparagraph": "\xB6",
6176
+ "\\textperiodcentered": "\xB7",
6177
+ "\\textellipsis": "\u2026",
6178
+ "\\textemdash": "\u2014",
6179
+ "\\textendash": "\u2013",
6180
+ "\\textregistered": "\xAE",
6181
+ "\\texttrademark": "\u2122",
6182
+ "\\textdegree": "\xB0"
6183
+ }[c] ?? c;
6184
+ }
5916
6185
  }
5917
6186
  if (runinStyle !== null && text) {
5918
6187
  runs.push(["Style", `'${text}'`, { dict: runinStyle }]);
@@ -5992,19 +6261,27 @@ var ComputeEngine = (() => {
5992
6261
  return ["Prime", missingIfEmpty(lhs)];
5993
6262
  return ["Prime", missingIfEmpty(lhs), order2];
5994
6263
  }
5995
- function parseDelimiter(_parser, body) {
6264
+ function parseParenDelimiter(_parser, body) {
5996
6265
  if (body === null || isEmptySequence(body))
5997
- return ["Sequence"];
6266
+ return ["Delimiter"];
6267
+ if (head(body) === "Delimiter" && op(body, 2)) {
6268
+ const delims = stringValue(op(body, 2));
6269
+ if (delims?.length === 1) {
6270
+ return ["Delimiter", op(body, 1) ?? ["Sequence"], { str: `(${delims})` }];
6271
+ }
6272
+ }
5998
6273
  if (head(body) === "Sequence") {
5999
6274
  if (nops(body) === 0)
6000
6275
  return ["Delimiter"];
6001
- return ["Delimiter", ["Sequence", ...ops(body) ?? []]];
6276
+ return ["Delimiter", body];
6002
6277
  }
6003
- return ["Delimiter", body];
6278
+ return ["Delimiter", ["Sequence", body]];
6004
6279
  }
6005
6280
  function parseList(_parser, body) {
6006
6281
  if (body === null || isEmptySequence(body))
6007
6282
  return ["List"];
6283
+ if (head(body) === "Delimiter")
6284
+ return parseList(_parser, op(body, 1));
6008
6285
  if (head(body) === "Range")
6009
6286
  return body;
6010
6287
  if (head(body) !== "Sequence" && head(body) !== "List")
@@ -6045,6 +6322,70 @@ var ComputeEngine = (() => {
6045
6322
  }
6046
6323
  return ["Range", start, end];
6047
6324
  }
6325
+ var DELIMITERS_SHORTHAND = {
6326
+ "(": "(",
6327
+ ")": ")",
6328
+ "[": "\\lbrack",
6329
+ "\u27E6": "\\llbrack",
6330
+ // U+27E6 MATHEMATICAL LEFT WHITE SQUARE BRACKET
6331
+ "\u27E7": "\\rrbrack",
6332
+ // U+27E7 MATHEMATICAL RIGHT WHITE SQUARE BRACKET
6333
+ "]": "\\rbrack",
6334
+ "{": "\\lbrace",
6335
+ "}": "\\rbrace",
6336
+ "<": "\\langle",
6337
+ ">": "\\rangle",
6338
+ // '|': '\\vert',
6339
+ "\u2016": "\\Vert",
6340
+ // U+2016 DOUBLE VERTICAL LINE
6341
+ "\\": "\\backslash",
6342
+ "\u2308": "\\lceil",
6343
+ // ⌈ U+2308 LEFT CEILING
6344
+ "\u2309": "\\rceil",
6345
+ // U+2309 RIGHT CEILING
6346
+ "\u230A": "\\lfloor",
6347
+ // ⌊ U+230A LEFT FLOOR
6348
+ "\u230B": "\\rfloor",
6349
+ // ⌋ U+230B RIGHT FLOOR
6350
+ "\u231C": "\\ulcorner",
6351
+ // ⌜ U+231C TOP LEFT CORNER
6352
+ "\u231D": "\\urcorner",
6353
+ // ⌝ U+231D TOP RIGHT CORNER
6354
+ "\u231E": "\\llcorner",
6355
+ // ⌞ U+231E BOTTOM LEFT CORNER
6356
+ "\u231F": "\\lrcorner",
6357
+ // ⌟ U+231F BOTTOM RIGHT CORNER
6358
+ "\u23B0": "\\lmoustache",
6359
+ // U+23B0 UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION
6360
+ "\u23B1": "\\rmoustache"
6361
+ // U+23B1 UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION
6362
+ // '⎹': '', // U+23B9 DIVIDES
6363
+ // '⎾': '', // U+23BE RIGHT PARENTHESIS UPPER HOOK
6364
+ // '⎿': '', // U+23BF RIGHT PARENTHESIS LOWER HOOK
6365
+ };
6366
+ function parseAssign(parser, lhs) {
6367
+ const index = parser.index;
6368
+ if (head(lhs) === "InvisibleOperator" && nops(lhs) === 2 && head(op(lhs, 2)) === "Delimiter" && head(op(op(lhs, 2), 1)) === "Sequence") {
6369
+ const fn = symbol(op(lhs, 1));
6370
+ if (!fn)
6371
+ return null;
6372
+ const args = ops(op(op(lhs, 2), 1));
6373
+ const rhs2 = parser.parseExpression({ minPrec: 0 });
6374
+ if (rhs2 === null) {
6375
+ parser.index = index;
6376
+ return null;
6377
+ }
6378
+ return ["Assign", fn, ["Function", rhs2, ...args ?? []]];
6379
+ }
6380
+ if (!symbol(lhs))
6381
+ return null;
6382
+ const rhs = parser.parseExpression({ minPrec: 0 });
6383
+ if (rhs === null) {
6384
+ parser.index = index;
6385
+ return null;
6386
+ }
6387
+ return ["Assign", lhs, rhs];
6388
+ }
6048
6389
 
6049
6390
  // src/compute-engine/latex-syntax/dictionary/definitions-inequalities.ts
6050
6391
  var DEFINITIONS_INEQUALITIES = [
@@ -6101,7 +6442,7 @@ var ComputeEngine = (() => {
6101
6442
  latexTrigger: ["\\leqslant"],
6102
6443
  kind: "infix",
6103
6444
  associativity: "right",
6104
- precedence: 265,
6445
+ precedence: COMPARISON_PRECEDENCE + 5,
6105
6446
  // Note different precedence than `<=` as per MathML
6106
6447
  parse: "LessEqual"
6107
6448
  },
@@ -6110,28 +6451,28 @@ var ComputeEngine = (() => {
6110
6451
  latexTrigger: ["\\lneqq"],
6111
6452
  kind: "infix",
6112
6453
  associativity: "right",
6113
- precedence: 260
6454
+ precedence: COMPARISON_PRECEDENCE
6114
6455
  },
6115
6456
  {
6116
6457
  name: "NotLessNotEqual",
6117
6458
  latexTrigger: ["\\nleqq"],
6118
6459
  kind: "infix",
6119
6460
  associativity: "right",
6120
- precedence: 260
6461
+ precedence: COMPARISON_PRECEDENCE
6121
6462
  },
6122
6463
  {
6123
6464
  name: "LessOverEqual",
6124
6465
  latexTrigger: ["\\leqq"],
6125
6466
  kind: "infix",
6126
6467
  associativity: "right",
6127
- precedence: 265
6468
+ precedence: COMPARISON_PRECEDENCE + 5
6128
6469
  },
6129
6470
  {
6130
6471
  name: "GreaterOverEqual",
6131
6472
  latexTrigger: ["\\geqq"],
6132
6473
  kind: "infix",
6133
6474
  associativity: "right",
6134
- precedence: 265,
6475
+ precedence: COMPARISON_PRECEDENCE + 5,
6135
6476
  parse: "GreaterEqual"
6136
6477
  },
6137
6478
  {
@@ -6139,13 +6480,13 @@ var ComputeEngine = (() => {
6139
6480
  latexTrigger: ["="],
6140
6481
  kind: "infix",
6141
6482
  associativity: "right",
6142
- precedence: 260
6483
+ precedence: COMPARISON_PRECEDENCE
6143
6484
  },
6144
6485
  {
6145
6486
  latexTrigger: ["*", "="],
6146
6487
  kind: "infix",
6147
6488
  associativity: "right",
6148
- precedence: 260,
6489
+ precedence: COMPARISON_PRECEDENCE,
6149
6490
  parse: "StarEqual"
6150
6491
  },
6151
6492
  {
@@ -6153,42 +6494,42 @@ var ComputeEngine = (() => {
6153
6494
  latexTrigger: ["\\star", "="],
6154
6495
  kind: "infix",
6155
6496
  associativity: "right",
6156
- precedence: 260
6497
+ precedence: COMPARISON_PRECEDENCE
6157
6498
  },
6158
6499
  {
6159
6500
  name: "PlusEqual",
6160
6501
  latexTrigger: ["+", "="],
6161
6502
  kind: "infix",
6162
6503
  associativity: "right",
6163
- precedence: 260
6504
+ precedence: COMPARISON_PRECEDENCE
6164
6505
  },
6165
6506
  {
6166
6507
  name: "MinusEqual",
6167
6508
  latexTrigger: ["-", "="],
6168
6509
  kind: "infix",
6169
6510
  associativity: "right",
6170
- precedence: 260
6511
+ precedence: COMPARISON_PRECEDENCE
6171
6512
  },
6172
6513
  {
6173
6514
  name: "SlashEqual",
6174
6515
  latexTrigger: ["/", "="],
6175
6516
  kind: "infix",
6176
6517
  associativity: "right",
6177
- precedence: 260
6518
+ precedence: COMPARISON_PRECEDENCE
6178
6519
  },
6179
6520
  {
6180
6521
  name: "EqualEqual",
6181
6522
  latexTrigger: ["=", "="],
6182
6523
  kind: "infix",
6183
6524
  associativity: "right",
6184
- precedence: 260
6525
+ precedence: COMPARISON_PRECEDENCE
6185
6526
  },
6186
6527
  {
6187
6528
  name: "EqualEqualEqual",
6188
6529
  latexTrigger: ["=", "=", "="],
6189
6530
  kind: "infix",
6190
6531
  associativity: "right",
6191
- precedence: 265
6532
+ precedence: COMPARISON_PRECEDENCE + 5
6192
6533
  },
6193
6534
  {
6194
6535
  name: "TildeFullEqual",
@@ -6196,7 +6537,7 @@ var ComputeEngine = (() => {
6196
6537
  latexTrigger: ["\\cong"],
6197
6538
  kind: "infix",
6198
6539
  associativity: "right",
6199
- precedence: 260
6540
+ precedence: COMPARISON_PRECEDENCE
6200
6541
  },
6201
6542
  {
6202
6543
  name: "NotTildeFullEqual",
@@ -6204,7 +6545,7 @@ var ComputeEngine = (() => {
6204
6545
  latexTrigger: ["\\ncong"],
6205
6546
  kind: "infix",
6206
6547
  associativity: "right",
6207
- precedence: 260
6548
+ precedence: COMPARISON_PRECEDENCE
6208
6549
  },
6209
6550
  {
6210
6551
  name: "Approx",
@@ -6228,7 +6569,7 @@ var ComputeEngine = (() => {
6228
6569
  latexTrigger: ["\\approxeq"],
6229
6570
  kind: "infix",
6230
6571
  associativity: "right",
6231
- precedence: 260
6572
+ precedence: COMPARISON_PRECEDENCE
6232
6573
  },
6233
6574
  {
6234
6575
  name: "NotApproxEqual",
@@ -6251,7 +6592,7 @@ var ComputeEngine = (() => {
6251
6592
  latexTrigger: ["!", "="],
6252
6593
  kind: "infix",
6253
6594
  associativity: "right",
6254
- precedence: 260
6595
+ precedence: COMPARISON_PRECEDENCE
6255
6596
  // Note different precedence than \\ne per MathML
6256
6597
  },
6257
6598
  {
@@ -6281,7 +6622,7 @@ var ComputeEngine = (() => {
6281
6622
  latexTrigger: ["\\geqslant"],
6282
6623
  kind: "infix",
6283
6624
  associativity: "right",
6284
- precedence: 265,
6625
+ precedence: COMPARISON_PRECEDENCE + 5,
6285
6626
  // Note: different precedence than `>=` as per MathML
6286
6627
  parse: "GreaterEqual"
6287
6628
  },
@@ -6290,14 +6631,14 @@ var ComputeEngine = (() => {
6290
6631
  latexTrigger: ["\\gneqq"],
6291
6632
  kind: "infix",
6292
6633
  associativity: "right",
6293
- precedence: 260
6634
+ precedence: COMPARISON_PRECEDENCE
6294
6635
  },
6295
6636
  {
6296
6637
  name: "NotGreaterNotEqual",
6297
6638
  latexTrigger: ["\\ngeqq"],
6298
6639
  kind: "infix",
6299
6640
  associativity: "right",
6300
- precedence: 260
6641
+ precedence: COMPARISON_PRECEDENCE
6301
6642
  },
6302
6643
  {
6303
6644
  latexTrigger: [">"],
@@ -6332,7 +6673,7 @@ var ComputeEngine = (() => {
6332
6673
  latexTrigger: ["\\circeq"],
6333
6674
  kind: "infix",
6334
6675
  associativity: "right",
6335
- precedence: 260
6676
+ precedence: COMPARISON_PRECEDENCE
6336
6677
  },
6337
6678
  {
6338
6679
  name: "TriangleEqual",
@@ -6340,7 +6681,7 @@ var ComputeEngine = (() => {
6340
6681
  latexTrigger: ["\\triangleq"],
6341
6682
  kind: "infix",
6342
6683
  associativity: "right",
6343
- precedence: 260
6684
+ precedence: COMPARISON_PRECEDENCE
6344
6685
  },
6345
6686
  {
6346
6687
  name: "DotEqual",
@@ -6348,7 +6689,7 @@ var ComputeEngine = (() => {
6348
6689
  latexTrigger: ["\\doteq"],
6349
6690
  kind: "infix",
6350
6691
  associativity: "right",
6351
- precedence: 265
6692
+ precedence: COMPARISON_PRECEDENCE + 5
6352
6693
  },
6353
6694
  {
6354
6695
  name: "DotEqualDot",
@@ -6356,7 +6697,7 @@ var ComputeEngine = (() => {
6356
6697
  latexTrigger: ["\\doteqdot"],
6357
6698
  kind: "infix",
6358
6699
  associativity: "right",
6359
- precedence: 265
6700
+ precedence: COMPARISON_PRECEDENCE + 5
6360
6701
  },
6361
6702
  {
6362
6703
  name: "FallingDotEqual",
@@ -6364,7 +6705,7 @@ var ComputeEngine = (() => {
6364
6705
  latexTrigger: ["\\fallingdotseq"],
6365
6706
  kind: "infix",
6366
6707
  associativity: "right",
6367
- precedence: 265
6708
+ precedence: COMPARISON_PRECEDENCE + 5
6368
6709
  },
6369
6710
  {
6370
6711
  name: "RisingDotEqual",
@@ -6372,77 +6713,77 @@ var ComputeEngine = (() => {
6372
6713
  latexTrigger: ["\\fallingdotseq"],
6373
6714
  kind: "infix",
6374
6715
  associativity: "right",
6375
- precedence: 265
6716
+ precedence: COMPARISON_PRECEDENCE + 5
6376
6717
  },
6377
6718
  {
6378
6719
  name: "QuestionEqual",
6379
6720
  latexTrigger: ["\\questeq"],
6380
6721
  kind: "infix",
6381
6722
  associativity: "right",
6382
- precedence: 260
6723
+ precedence: COMPARISON_PRECEDENCE
6383
6724
  },
6384
6725
  {
6385
6726
  name: "MuchLess",
6386
6727
  latexTrigger: ["\\ll"],
6387
6728
  kind: "infix",
6388
6729
  associativity: "right",
6389
- precedence: 260
6730
+ precedence: COMPARISON_PRECEDENCE
6390
6731
  },
6391
6732
  {
6392
6733
  name: "MuchGreater",
6393
6734
  latexTrigger: ["\\gg"],
6394
6735
  kind: "infix",
6395
6736
  associativity: "right",
6396
- precedence: 260
6737
+ precedence: COMPARISON_PRECEDENCE
6397
6738
  },
6398
6739
  {
6399
6740
  name: "Precedes",
6400
6741
  latexTrigger: ["\\prec"],
6401
6742
  kind: "infix",
6402
6743
  associativity: "right",
6403
- precedence: 260
6744
+ precedence: COMPARISON_PRECEDENCE
6404
6745
  },
6405
6746
  {
6406
6747
  name: "Succeeds",
6407
6748
  latexTrigger: ["\\succ"],
6408
6749
  kind: "infix",
6409
6750
  associativity: "right",
6410
- precedence: 260
6751
+ precedence: COMPARISON_PRECEDENCE
6411
6752
  },
6412
6753
  {
6413
6754
  name: "PrecedesEqual",
6414
6755
  latexTrigger: ["\\preccurlyeq"],
6415
6756
  kind: "infix",
6416
6757
  associativity: "right",
6417
- precedence: 260
6758
+ precedence: COMPARISON_PRECEDENCE
6418
6759
  },
6419
6760
  {
6420
6761
  name: "SucceedsEqual",
6421
6762
  latexTrigger: ["\\curlyeqprec"],
6422
6763
  kind: "infix",
6423
6764
  associativity: "right",
6424
- precedence: 260
6765
+ precedence: COMPARISON_PRECEDENCE
6425
6766
  },
6426
6767
  {
6427
6768
  name: "NotPrecedes",
6428
6769
  latexTrigger: ["\\nprec"],
6429
6770
  kind: "infix",
6430
6771
  associativity: "right",
6431
- precedence: 260
6772
+ precedence: COMPARISON_PRECEDENCE
6432
6773
  },
6433
6774
  {
6434
6775
  name: "NotSucceeds",
6435
6776
  latexTrigger: ["\\nsucc"],
6436
6777
  kind: "infix",
6437
6778
  associativity: "right",
6438
- precedence: 260
6779
+ precedence: COMPARISON_PRECEDENCE
6439
6780
  },
6440
6781
  {
6441
6782
  name: "Between",
6442
6783
  latexTrigger: ["\\between"],
6443
6784
  kind: "infix",
6444
6785
  associativity: "right",
6445
- precedence: 265
6786
+ precedence: COMPARISON_PRECEDENCE + 5
6446
6787
  }
6447
6788
  ];
6448
6789
 
@@ -6596,7 +6937,15 @@ var ComputeEngine = (() => {
6596
6937
  kind: "infix",
6597
6938
  associativity: "right",
6598
6939
  precedence: 219,
6599
- parse: "Equivalent"
6940
+ parse: (parser, lhs, terminator) => {
6941
+ const rhs = parser.parseExpression({ ...terminator, minPrec: 219 });
6942
+ const index = parser.index;
6943
+ const modulus = parser.parseExpression({ ...terminator, minPrec: 219 });
6944
+ if (modulus && head(modulus) === "Mod")
6945
+ return ["Congruent", lhs, rhs, missingIfEmpty(op(modulus, 1))];
6946
+ parser.index = index;
6947
+ return ["Equivalent", lhs, missingIfEmpty(rhs)];
6948
+ }
6600
6949
  },
6601
6950
  {
6602
6951
  name: "Proves",
@@ -7349,6 +7698,9 @@ var ComputeEngine = (() => {
7349
7698
  parse: (_parser, body) => {
7350
7699
  if (body === null || isEmptySequence(body))
7351
7700
  return "EmptySet";
7701
+ if (head(body) == "Delimiter" && stringValue(op(body, 2)) === ",") {
7702
+ body = op(body, 1);
7703
+ }
7352
7704
  if (head(body) !== "Sequence")
7353
7705
  return ["Set", body];
7354
7706
  return ["Set", ...ops(body) ?? []];
@@ -7373,7 +7725,7 @@ var ComputeEngine = (() => {
7373
7725
  // or \\ominus
7374
7726
  kind: "infix",
7375
7727
  // @todo: parser could check that lhs and rhs are sets
7376
- precedence: 260
7728
+ precedence: COMPARISON_PRECEDENCE
7377
7729
  },
7378
7730
  // Predicates/Relations
7379
7731
  {
@@ -7707,7 +8059,10 @@ var ComputeEngine = (() => {
7707
8059
  const op12 = op(expr, 1);
7708
8060
  if (!op12)
7709
8061
  return [expr, null];
7710
- if (h === "Multiply") {
8062
+ if (h === "Sequence" && nops(expr) === 1) {
8063
+ return parseIntegralBodyExpression(op12);
8064
+ }
8065
+ if (h === "Multiply" || h === "InvisibleOperator") {
7711
8066
  const args = ops(expr);
7712
8067
  if (args && args.length > 1) {
7713
8068
  const sym = symbol(args[args.length - 2]);
@@ -7730,7 +8085,7 @@ var ComputeEngine = (() => {
7730
8085
  if (index) {
7731
8086
  if (!fn2)
7732
8087
  return [null, index];
7733
- return [["Delimiter", fn2, ...ops(expr).slice(1)], index];
8088
+ return [["Delimiter", ["Sequence", fn2], ...ops(expr).slice(1)], index];
7734
8089
  }
7735
8090
  } else if (h === "Add") {
7736
8091
  const args = ops(expr);
@@ -8805,7 +9160,6 @@ var ComputeEngine = (() => {
8805
9160
  avoidExponentsInRange: [-7, 20]
8806
9161
  };
8807
9162
  var DEFAULT_PARSE_LATEX_OPTIONS = {
8808
- applyInvisibleOperator: "auto",
8809
9163
  skipSpace: true,
8810
9164
  parseArgumentsOfUnknownLatexCommands: true,
8811
9165
  parseNumbers: "auto",
@@ -9209,11 +9563,12 @@ var ComputeEngine = (() => {
9209
9563
  this.skipSpace();
9210
9564
  if (this.matchBoundary())
9211
9565
  return expr ?? ["Sequence"];
9212
- const from = this.index;
9213
9566
  while (!this.matchBoundary() && !this.atEnd)
9214
9567
  this.nextToken();
9215
- const err = this.error("syntax-error", from);
9216
- return expr ? ["Sequence", expr, err] : err;
9568
+ if (head(expr) === "Error")
9569
+ return expr;
9570
+ const err = this.error("expected-closing-delimiter", start);
9571
+ return expr ? ["InvisibleOperator", expr, err] : err;
9217
9572
  }
9218
9573
  this.index = start;
9219
9574
  return null;
@@ -9360,7 +9715,7 @@ var ComputeEngine = (() => {
9360
9715
  }
9361
9716
  parseDecimalDigits(options) {
9362
9717
  options ?? (options = {});
9363
- options.withGrouping ?? (options.withGrouping = false);
9718
+ options.withGrouping ?? (options.withGrouping = true);
9364
9719
  const result = [];
9365
9720
  let done = false;
9366
9721
  while (!done) {
@@ -9385,7 +9740,7 @@ var ComputeEngine = (() => {
9385
9740
  }
9386
9741
  parseSignedInteger(options) {
9387
9742
  options ?? (options = {});
9388
- options.withGrouping ?? (options.withGrouping = false);
9743
+ options.withGrouping ?? (options.withGrouping = true);
9389
9744
  const start = this.index;
9390
9745
  const sign2 = this.parseOptionalSign();
9391
9746
  const result = this.parseDecimalDigits(options);
@@ -9425,7 +9780,7 @@ var ComputeEngine = (() => {
9425
9780
  this.skipSpaceTokens();
9426
9781
  if (this.matchAll(this._beginExponentMarkerTokens)) {
9427
9782
  this.skipSpaceTokens();
9428
- const exponent = this.parseSignedInteger();
9783
+ const exponent = this.parseSignedInteger({ withGrouping: false });
9429
9784
  this.skipSpaceTokens();
9430
9785
  if (this.matchAll(this._endExponentMarkerTokens) && exponent)
9431
9786
  return exponent;
@@ -9480,7 +9835,14 @@ var ComputeEngine = (() => {
9480
9835
  return null;
9481
9836
  const start = this.index;
9482
9837
  this.skipVisualSpace();
9483
- this.match("+");
9838
+ let sign2 = 1;
9839
+ while (this.peek === "-" || this.peek === "+") {
9840
+ if (this.match("-"))
9841
+ sign2 *= -1;
9842
+ else
9843
+ this.match("+");
9844
+ this.skipVisualSpace();
9845
+ }
9484
9846
  let wholePart = "";
9485
9847
  let fractionalPart = "";
9486
9848
  let startsWithDecimalMarker = false;
@@ -9491,21 +9853,17 @@ var ComputeEngine = (() => {
9491
9853
  wholePart = "0";
9492
9854
  }
9493
9855
  } else
9494
- wholePart = this.parseDecimalDigits({ withGrouping: true });
9856
+ wholePart = this.parseDecimalDigits();
9495
9857
  if (!wholePart) {
9496
9858
  this.index = start;
9497
9859
  return null;
9498
9860
  }
9499
9861
  const fractionalIndex = this.index;
9500
- let hasFractionalPart = true;
9862
+ let hasFractionalPart = false;
9501
9863
  if (startsWithDecimalMarker || this.match(".") || this.matchAll(this._decimalMarkerTokens)) {
9502
- fractionalPart = this.parseDecimalDigits({ withGrouping: true });
9503
- if (!fractionalPart) {
9504
- this.index = fractionalIndex;
9505
- return { num: wholePart };
9506
- }
9507
- } else
9508
- hasFractionalPart = false;
9864
+ fractionalPart = this.parseDecimalDigits();
9865
+ hasFractionalPart = true;
9866
+ }
9509
9867
  let hasRepeatingPart = false;
9510
9868
  if (hasFractionalPart) {
9511
9869
  const repeat = this.parseRepeatingDecimal();
@@ -9515,14 +9873,18 @@ var ComputeEngine = (() => {
9515
9873
  } else if (this.match("\\ldots") || this.matchAll(this._truncationMarkerTokens)) {
9516
9874
  }
9517
9875
  }
9876
+ if (hasFractionalPart && !fractionalPart) {
9877
+ this.index = fractionalIndex;
9878
+ return { num: sign2 < 0 ? "-" + wholePart : wholePart };
9879
+ }
9518
9880
  this.skipVisualSpace();
9519
9881
  const exponent = this.parseExponent();
9520
9882
  if (!hasRepeatingPart && this.options.parseNumbers === "rational") {
9521
9883
  const whole = parseInt(wholePart, 10);
9522
9884
  if (!fractionalPart) {
9523
9885
  if (exponent)
9524
- return ["Multiply", whole, ["Power", 10, exponent]];
9525
- return whole;
9886
+ return ["Multiply", sign2 * whole, ["Power", 10, exponent]];
9887
+ return sign2 * whole;
9526
9888
  }
9527
9889
  const fraction = parseInt(fractionalPart, 10);
9528
9890
  const n = fractionalPart.length;
@@ -9531,14 +9893,14 @@ var ComputeEngine = (() => {
9531
9893
  if (exponent) {
9532
9894
  return [
9533
9895
  "Multiply",
9534
- ["Rational", numerator, denominator],
9896
+ ["Rational", sign2 * numerator, denominator],
9535
9897
  ["Power", 10, exponent]
9536
9898
  ];
9537
9899
  }
9538
- return ["Rational", numerator, denominator];
9900
+ return ["Rational", sign2 * numerator, denominator];
9539
9901
  }
9540
9902
  return {
9541
- num: wholePart + (hasFractionalPart ? "." + fractionalPart : "") + (exponent ? "e" + exponent : "")
9903
+ num: (sign2 < 0 ? "-" : "") + wholePart + (hasFractionalPart ? "." + fractionalPart : "") + (exponent ? "e" + exponent : "")
9542
9904
  };
9543
9905
  }
9544
9906
  /**
@@ -9666,8 +10028,13 @@ var ComputeEngine = (() => {
9666
10028
  return getSequence(group) ?? [];
9667
10029
  }
9668
10030
  if (kind === "implicit") {
9669
- if (head(group) === "Delimiter")
9670
- return getSequence(group) ?? [];
10031
+ if (head(group) === "Delimiter") {
10032
+ if (head(op1(group)) === "Sequence") {
10033
+ const seq = op1(op1(group));
10034
+ return seq ? [seq] : [];
10035
+ }
10036
+ return op1(group) ? [op1(group)] : [];
10037
+ }
9671
10038
  if (group !== null)
9672
10039
  return [group];
9673
10040
  const primary = this.parseExpression({ ...until, minPrec: 390 });
@@ -9926,7 +10293,7 @@ var ComputeEngine = (() => {
9926
10293
  );
9927
10294
  if (defs) {
9928
10295
  const nonEmptySuperscripts = superscripts.filter(
9929
- (x) => head(x) !== "Sequence"
10296
+ (x) => !(head(x) === "Sequence" && nops(x) === 0)
9930
10297
  );
9931
10298
  if (nonEmptySuperscripts.length !== 0) {
9932
10299
  const superscriptExpression = nonEmptySuperscripts.length === 1 ? nonEmptySuperscripts[0] : ["List", ...nonEmptySuperscripts];
@@ -9995,75 +10362,6 @@ var ComputeEngine = (() => {
9995
10362
  }
9996
10363
  return result;
9997
10364
  }
9998
- /**
9999
- * Apply an invisible operator between two expressions.
10000
- *
10001
- * If the `lhs` is an literal integer and the `rhs` is a literal rational
10002
- * -> 'invisible plus'
10003
- *
10004
- * That is '2 3/4' -> ['Add', 2, ['Rational', 3, 4]]
10005
- *
10006
- * If `lhs` is a number and `rhs` is a number but not a literal -> 'invisible multiply'.
10007
- * - 2x
10008
- * - 2(x+1)
10009
- * - x(x+1)
10010
- * - f(x)g(y)
10011
- * - 2 sin(x)
10012
- * - 2 f(x)
10013
- * - x f(x)
10014
- * - (x-1)(x+1)
10015
- * - (x+1)2 -> no
10016
- * - x2 -> no
10017
- * => lhs is a number, rhs is a number, but not a literal
10018
- */
10019
- applyInvisibleOperator(until, lhs) {
10020
- if (lhs === null || this.options.applyInvisibleOperator === null || head(lhs) === "Error" || symbol(lhs) === "Nothing" || isEmptySequence(lhs) || this.atTerminator(until))
10021
- return null;
10022
- if (this.peekDefinitions("operator").length > 0)
10023
- return null;
10024
- if (this.isFunctionHead(lhs)) {
10025
- const args = this.parseArguments("enclosure", { ...until, minPrec: 0 });
10026
- if (args === null)
10027
- return null;
10028
- return [lhs, ...args];
10029
- }
10030
- const start = this.index;
10031
- const rhs = this.parseExpression({ ...until, minPrec: 390 });
10032
- if (rhs === null || symbol(rhs) === "Nothing" || isEmptySequence(rhs)) {
10033
- this.index = start;
10034
- return null;
10035
- }
10036
- if (head(rhs) === "Error")
10037
- return applyAssociativeOperator("Sequence", lhs, rhs);
10038
- if (typeof this.options.applyInvisibleOperator === "function")
10039
- return this.options.applyInvisibleOperator(this, lhs, rhs);
10040
- if (this.isFunctionHead(lhs)) {
10041
- const seq = getSequence(rhs);
10042
- return seq ? [lhs, ...seq] : lhs;
10043
- }
10044
- const lhsNumber = machineValue(lhs);
10045
- if (lhsNumber !== null && Number.isInteger(lhsNumber)) {
10046
- const rhsHead = head(rhs);
10047
- if (rhsHead === "Divide" || rhsHead === "Rational") {
10048
- const [n, d] = [machineValue(op(rhs, 1)), machineValue(op(rhs, 2))];
10049
- if (n !== null && d !== null && n > 0 && n <= 1e3 && d > 1 && d <= 1e3 && Number.isInteger(n) && Number.isInteger(d))
10050
- return ["Add", lhs, rhs];
10051
- }
10052
- }
10053
- if (head(rhs) === "Delimiter") {
10054
- if (head(op(rhs, 1)) === "Sequence")
10055
- return [lhs, ...ops(op(rhs, 1)) ?? []];
10056
- if (!op(rhs, 1) || symbol(op(rhs, 1)) === "Nothing")
10057
- return applyAssociativeOperator(
10058
- "Sequence",
10059
- lhs,
10060
- this.error("expected-expression", start)
10061
- );
10062
- }
10063
- if (head(rhs) === "Sequence" || head(lhs) === "Sequence" || stringValue(lhs) !== null || stringValue(rhs) !== null || dictionary(lhs) !== null || dictionary(rhs) !== null)
10064
- return applyAssociativeOperator("Sequence", lhs, rhs);
10065
- return applyAssociativeOperator("Multiply", lhs, rhs);
10066
- }
10067
10365
  /**
10068
10366
  * This method can be invoked when we know we're in an error situation.
10069
10367
  *
@@ -10269,7 +10567,23 @@ var ComputeEngine = (() => {
10269
10567
  this.skipSpace();
10270
10568
  let result = this.parseInfixOperator(lhs, until);
10271
10569
  if (result === null) {
10272
- result = this.applyInvisibleOperator(until, lhs);
10570
+ if (this.peekDefinitions("operator").length === 0) {
10571
+ const rhs = this.parseExpression({
10572
+ ...until,
10573
+ minPrec: MULTIPLICATION_PRECEDENCE
10574
+ });
10575
+ if (rhs !== null) {
10576
+ if (head(lhs) === "InvisibleOperator") {
10577
+ if (head(rhs) === "InvisibleOperator")
10578
+ result = ["InvisibleOperator", ...ops(lhs), ...ops(rhs)];
10579
+ else
10580
+ result = ["InvisibleOperator", ...ops(lhs), rhs];
10581
+ } else if (head(rhs) === "InvisibleOperator") {
10582
+ result = ["InvisibleOperator", lhs, ...ops(rhs)];
10583
+ } else
10584
+ result = ["InvisibleOperator", lhs, rhs];
10585
+ }
10586
+ }
10273
10587
  }
10274
10588
  if (result !== null) {
10275
10589
  lhs = result;
@@ -10278,11 +10592,6 @@ var ComputeEngine = (() => {
10278
10592
  }
10279
10593
  }
10280
10594
  }
10281
- if (!lhs) {
10282
- lhs = this.parseSyntaxError();
10283
- while (!this.atTerminator(until))
10284
- this.nextToken();
10285
- }
10286
10595
  return this.decorate(lhs, start);
10287
10596
  }
10288
10597
  /**
@@ -10608,7 +10917,7 @@ var ComputeEngine = (() => {
10608
10917
  sansserif: (s) => `\\mathsf{${s}}`,
10609
10918
  monospace: (s) => `\\mathtt{${s}}`
10610
10919
  };
10611
- var Serializer2 = class {
10920
+ var Serializer4 = class {
10612
10921
  constructor(options, dictionary2, onError) {
10613
10922
  this.level = -1;
10614
10923
  this.options = options;
@@ -10690,10 +10999,24 @@ var ComputeEngine = (() => {
10690
10999
  return s;
10691
11000
  if (fence === void 0)
10692
11001
  fence = "()";
10693
- const openFence = fence?.[0] ?? ".";
10694
- const closeFence = fence?.[1] ?? ".";
11002
+ let openFence = fence?.[0] ?? ".";
11003
+ let closeFence = fence?.[1] ?? ".";
10695
11004
  if ((openFence === "." || closeFence === ".") && style === "paren")
10696
11005
  style = "leftright";
11006
+ if (openFence === '"')
11007
+ openFence = "``";
11008
+ else if (openFence === "|")
11009
+ openFence = "\\lvert";
11010
+ else
11011
+ openFence = DELIMITERS_SHORTHAND[openFence] ?? openFence;
11012
+ if (closeFence === '"')
11013
+ closeFence = "''";
11014
+ else if (closeFence === "|")
11015
+ closeFence = "\\rvert";
11016
+ else
11017
+ closeFence = DELIMITERS_SHORTHAND[closeFence] ?? closeFence;
11018
+ if (openFence === "." && closeFence === ".")
11019
+ return s;
10697
11020
  if (style === "leftright")
10698
11021
  return `\\left${openFence}${s}\\right${closeFence}}`;
10699
11022
  if (style === "big")
@@ -11086,7 +11409,7 @@ var ComputeEngine = (() => {
11086
11409
  get serializer() {
11087
11410
  if (this._serializer)
11088
11411
  return this._serializer;
11089
- this._serializer = new Serializer2(
11412
+ this._serializer = new Serializer4(
11090
11413
  this.options,
11091
11414
  this._dictionary,
11092
11415
  this.onError
@@ -13550,11 +13873,19 @@ var ComputeEngine = (() => {
13550
13873
  return result;
13551
13874
  }
13552
13875
  function flattenSequence(xs) {
13553
- if (xs.every((x) => x.head !== "Sequence"))
13876
+ if (xs.every((x) => x.head !== "Sequence" && x.head !== "Delimiter"))
13554
13877
  return xs;
13555
13878
  const ys = [];
13556
13879
  for (const x of xs) {
13557
- if (x.isValid && x.head === "Sequence") {
13880
+ if (!x.isValid)
13881
+ ys.push(x);
13882
+ else if (x.head === "Delimiter") {
13883
+ const seq = x.op1.ops ?? [];
13884
+ if (seq.length === 0)
13885
+ ys.push(x.engine.box(["Tupple"]));
13886
+ else
13887
+ ys.push(...flattenSequence(seq));
13888
+ } else if (x.head === "Sequence") {
13558
13889
  if (x.ops)
13559
13890
  ys.push(...x.ops);
13560
13891
  } else
@@ -13900,7 +14231,7 @@ var ComputeEngine = (() => {
13900
14231
  LogicOperators: [
13901
14232
  "FunctionOf",
13902
14233
  "Booleans",
13903
- ["OptArg", "Booleans"],
14234
+ ["VarArg", "Booleans"],
13904
14235
  "Booleans"
13905
14236
  ],
13906
14237
  Predicates: ["FunctionOf", "Anything", ["VarArg", "Anything"], "Booleans"],
@@ -14220,7 +14551,7 @@ var ComputeEngine = (() => {
14220
14551
  }
14221
14552
  function checkNumericArgs(ce, ops2, options) {
14222
14553
  let count = typeof options === "number" ? options : options?.count;
14223
- const flatten = typeof options === "number" ? true : options?.flatten ?? true;
14554
+ const flatten = typeof options === "number" || (options?.flatten ?? true);
14224
14555
  ops2 = canonical(ops2);
14225
14556
  if (flatten)
14226
14557
  ops2 = flattenSequence(ops2);
@@ -14281,7 +14612,7 @@ var ComputeEngine = (() => {
14281
14612
  x.infer(ce.Numbers);
14282
14613
  return xs;
14283
14614
  }
14284
- function checkArg(ce, arg, dom) {
14615
+ function checkDomain(ce, arg, dom) {
14285
14616
  if (arg === void 0 || arg === null)
14286
14617
  return ce.error("missing");
14287
14618
  if (dom === void 0)
@@ -14295,12 +14626,22 @@ var ComputeEngine = (() => {
14295
14626
  return arg;
14296
14627
  return ce.domainError(dom, arg.domain, arg);
14297
14628
  }
14298
- function checkArgs(ce, args, doms) {
14629
+ function checkPure(ce, arg) {
14630
+ if (arg === void 0 || arg === null)
14631
+ return ce.error("missing");
14632
+ arg = arg.canonical;
14633
+ if (!arg.isValid)
14634
+ return arg;
14635
+ if (arg.isPure)
14636
+ return arg;
14637
+ return ce.error("expected-pure-expression", arg);
14638
+ }
14639
+ function checkDomains(ce, args, doms) {
14299
14640
  if (args.length === doms.length && args.every((x, i) => !x.domain || x.domain.isCompatible(doms[i])))
14300
14641
  return args;
14301
14642
  const xs = [];
14302
14643
  for (let i = 0; i <= doms.length - 1; i++)
14303
- xs.push(checkArg(ce, args[i], doms[i]));
14644
+ xs.push(checkDomain(ce, args[i], doms[i]));
14304
14645
  for (let i = doms.length; i <= args.length - 1; i++)
14305
14646
  xs.push(ce.error("unexpected-argument", args[i]));
14306
14647
  return xs;
@@ -14476,9 +14817,9 @@ var ComputeEngine = (() => {
14476
14817
  } else
14477
14818
  index = ce.domainError("Symbols", index.domain, index);
14478
14819
  if (lower && lower.isFinite)
14479
- lower = checkArg(ce, lower, "Integers");
14820
+ lower = checkDomain(ce, lower, "Integers");
14480
14821
  if (upper && upper.isFinite)
14481
- upper = checkArg(ce, upper, "Integers");
14822
+ upper = checkDomain(ce, upper, "Integers");
14482
14823
  if (lower && upper)
14483
14824
  return ce.tuple([index, lower, upper]);
14484
14825
  if (upper)
@@ -14567,7 +14908,11 @@ var ComputeEngine = (() => {
14567
14908
  Limit: (args, compile2) => `_SYS.limit(${compile2(args[0])}, ${compile2(args[1])})`,
14568
14909
  Ln: "Math.log",
14569
14910
  List: (args, compile2) => `[${args.map((x) => compile2(x)).join(", ")}]`,
14570
- Log: "Math.log10",
14911
+ Log: (args, compile2) => {
14912
+ if (args.length === 1)
14913
+ return `Math.log(${compile2(args[0])})`;
14914
+ return `(Math.log(${compile2(args[0])}) / Math.log(${compile2(args[1])}))`;
14915
+ },
14571
14916
  LogGamma: "_SYS.lngamma",
14572
14917
  Lb: "Math.log2",
14573
14918
  Max: "Math.max",
@@ -14803,6 +15148,12 @@ var ComputeEngine = (() => {
14803
15148
  return compileLoop(h, args, target);
14804
15149
  if (args.every((x) => !isCollection(x))) {
14805
15150
  const op3 = target.operators?.(h);
15151
+ if ((h === "NotEqual" || h === "Equal" || h === "Less" || h === "Greater" || h === "LessEqual" || h === "GreaterEqual") && args.length > 2 && op3) {
15152
+ const result = [];
15153
+ for (let i = 0; i < args.length - 1; i++)
15154
+ result.push(compileExpr(h, [args[i], args[i + 1]], op3[1], target));
15155
+ return `(${result.join(") && (")})`;
15156
+ }
14806
15157
  if (op3 !== void 0) {
14807
15158
  if (args === null)
14808
15159
  return "";
@@ -19896,6 +20247,12 @@ var ComputeEngine = (() => {
19896
20247
  complexity: 9e3,
19897
20248
  signature: {
19898
20249
  domain: ["FunctionOf", "Numbers", "Numbers"],
20250
+ canonical: (ce, args) => {
20251
+ const base = args[0];
20252
+ if (base instanceof BoxedNumber && base.isNegative)
20253
+ return ce.neg(ce._fn("Factorial", [ce.neg(base)]));
20254
+ return ce._fn("Factorial", [base]);
20255
+ },
19899
20256
  evaluate: (ce, ops2) => {
19900
20257
  const n = asSmallInteger(ops2[0]);
19901
20258
  if (n !== null && n >= 0) {
@@ -19994,7 +20351,7 @@ var ComputeEngine = (() => {
19994
20351
  domain: ["FunctionOf", "Numbers", ["OptArg", "Numbers"], "Numbers"],
19995
20352
  canonical: (ce, ops2) => {
19996
20353
  if (ops2.length === 1)
19997
- return ce._fn("Log", [checkArg(ce, ops2[0], "Numbers")]);
20354
+ return ce._fn("Log", [checkDomain(ce, ops2[0], "Numbers")]);
19998
20355
  ops2 = checkNumericArgs(ce, ops2, 2);
19999
20356
  if (ops2.length !== 2)
20000
20357
  return ce._fn("Log", ops2);
@@ -20051,6 +20408,27 @@ var ComputeEngine = (() => {
20051
20408
  )
20052
20409
  }
20053
20410
  },
20411
+ Mod: {
20412
+ description: "Modulo",
20413
+ wikidata: "Q1799665",
20414
+ complexity: 2500,
20415
+ threadable: true,
20416
+ signature: {
20417
+ domain: ["FunctionOf", "Numbers", "Numbers", "Numbers"],
20418
+ evaluate: (ce, ops2) => {
20419
+ if (ops2.length !== 2)
20420
+ return void 0;
20421
+ const [lhs, rhs] = ops2;
20422
+ const nLhs = lhs.value;
20423
+ const nRhs = rhs.value;
20424
+ if (typeof nLhs !== "number")
20425
+ return void 0;
20426
+ if (typeof nRhs !== "number")
20427
+ return void 0;
20428
+ return ce.number((nLhs % nRhs + nRhs) % nRhs);
20429
+ }
20430
+ }
20431
+ },
20054
20432
  Multiply: {
20055
20433
  wikidata: "Q40276",
20056
20434
  associative: true,
@@ -20128,7 +20506,10 @@ var ComputeEngine = (() => {
20128
20506
  args = checkNumericArgs(ce, args, 2);
20129
20507
  if (args.length !== 2)
20130
20508
  return ce._fn("Power", args);
20131
- return ce.pow(args[0], args[1]);
20509
+ const [base, exp2] = args;
20510
+ if (base instanceof BoxedNumber && base.isNegative)
20511
+ return ce.neg(ce.pow(base, exp2));
20512
+ return ce.pow(base, exp2);
20132
20513
  },
20133
20514
  simplify: (ce, ops2) => processPower(ce, ops2[0], ops2[1], "simplify"),
20134
20515
  evaluate: (ce, ops2) => processPower(ce, ops2[0], ops2[1], "evaluate"),
@@ -20162,9 +20543,9 @@ var ComputeEngine = (() => {
20162
20543
  return ce._fn("Rational", [ce.error("missing")]);
20163
20544
  if (args.length === 1)
20164
20545
  return ce._fn("Rational", [
20165
- checkArg(ce, args[0], "ExtendedRealNumbers")
20546
+ checkDomain(ce, args[0], "ExtendedRealNumbers")
20166
20547
  ]);
20167
- args = checkArgs(ce, args, ["Integers", "Integers"]);
20548
+ args = checkDomains(ce, args, ["Integers", "Integers"]);
20168
20549
  if (args.length !== 2 || !args[0].isValid || !args[1].isValid)
20169
20550
  return ce._fn("Rational", args);
20170
20551
  return ce.div(args[0], args[1]);
@@ -20325,7 +20706,7 @@ var ComputeEngine = (() => {
20325
20706
  domain: ["FunctionOf", "Numbers", ["OptArg", "Numbers"], "Numbers"],
20326
20707
  canonical: (ce, args) => {
20327
20708
  if (args.length === 1) {
20328
- const x = checkArg(ce, args[0], "Numbers");
20709
+ const x = checkDomain(ce, args[0], "Numbers");
20329
20710
  if (x.isValid)
20330
20711
  return ce.neg(x);
20331
20712
  }
@@ -21376,7 +21757,6 @@ var ComputeEngine = (() => {
21376
21757
  "Numbers"
21377
21758
  ],
21378
21759
  canonical: (ce, ops2) => {
21379
- const body = ops2[0] ?? ce.error("missing");
21380
21760
  let range = ops2[1];
21381
21761
  let index = null;
21382
21762
  let lower = null;
@@ -21396,9 +21776,9 @@ var ComputeEngine = (() => {
21396
21776
  if (!index.symbol)
21397
21777
  index = ce.domainError("Symbols", index.domain, index);
21398
21778
  if (lower)
21399
- lower = checkArg(ce, lower, ce.Numbers);
21779
+ lower = checkDomain(ce, lower, ce.Numbers);
21400
21780
  if (upper)
21401
- upper = checkArg(ce, upper, ce.Numbers);
21781
+ upper = checkDomain(ce, upper, ce.Numbers);
21402
21782
  if (lower && upper)
21403
21783
  range = ce.tuple([index, lower, upper]);
21404
21784
  else if (upper)
@@ -21407,7 +21787,11 @@ var ComputeEngine = (() => {
21407
21787
  range = ce.tuple([index, lower]);
21408
21788
  else
21409
21789
  range = index;
21410
- return ce._fn("Integrate", [body.canonical, range]);
21790
+ let body = ops2[0] ?? ce.error("missing");
21791
+ body = body.canonical;
21792
+ if (body.head === "Delimiter" && body.op1.head === "Sequence")
21793
+ body = body.op1.op1;
21794
+ return ce._fn("Integrate", [body, range]);
21411
21795
  }
21412
21796
  }
21413
21797
  },
@@ -21440,15 +21824,12 @@ var ComputeEngine = (() => {
21440
21824
  //
21441
21825
  // Data Structures
21442
21826
  //
21443
- Sequence: {
21444
- signature: {
21445
- domain: "Functions"
21446
- }
21447
- },
21448
21827
  List: {
21449
21828
  complexity: 8200,
21829
+ hold: "all",
21450
21830
  signature: {
21451
- domain: ["FunctionOf", ["VarArg", "Anything"], "Lists"]
21831
+ domain: ["FunctionOf", ["VarArg", "Anything"], "Lists"],
21832
+ canonical: canonicalList
21452
21833
  },
21453
21834
  size: (expr) => expr.nops,
21454
21835
  iterator: (expr, start, count) => {
@@ -21603,7 +21984,7 @@ var ComputeEngine = (() => {
21603
21984
  signature: {
21604
21985
  domain: ["FunctionOf", "Strings", "Anything", "Tuples"],
21605
21986
  canonical: (ce, args) => {
21606
- const [key, value] = checkArgs(ce, args, [ce.Strings, "Values"]);
21987
+ const [key, value] = checkDomains(ce, args, [ce.Strings, "Values"]);
21607
21988
  if (!key.isValid || !value.isValid)
21608
21989
  return ce._fn("KeyValuePair", [key, value]);
21609
21990
  return ce.tuple([key, value]);
@@ -22189,6 +22570,17 @@ var ComputeEngine = (() => {
22189
22570
  }
22190
22571
  return result;
22191
22572
  }
22573
+ function canonicalList(ce, ops2) {
22574
+ ops2 = ops2.map((op3) => {
22575
+ if (op3.head === "Delimiter") {
22576
+ if (op3.op1.head === "Sequence")
22577
+ return ce._fn("List", canonical(op3.op1.ops));
22578
+ return ce._fn("List", [op3.op1?.canonical ?? ce.Nothing]);
22579
+ }
22580
+ return op3.canonical;
22581
+ });
22582
+ return ce._fn("List", ops2);
22583
+ }
22192
22584
 
22193
22585
  // src/compute-engine/library/control-structures.ts
22194
22586
  var CONTROL_STRUCTURES_LIBRARY = [
@@ -22624,19 +23016,172 @@ var ComputeEngine = (() => {
22624
23016
  // Inert functions
22625
23017
  //
22626
23018
  {
23019
+ /**
23020
+ * ## THEORY OF OPERATIONS: SEQUENCES
23021
+ *
23022
+ * There are two similar functions used to represent sequences of
23023
+ * expressions:
23024
+ *
23025
+ * - `InvisibleOperator` represent a sequence of expressions
23026
+ * that are syntactically juxtaposed without any separator or
23027
+ * operators combining them. For example, `2x` is represented as
23028
+ * `["InvisibleOperator", 2, "x"]`. `InvisibleOperator` gets
23029
+ * transformed into `Multiply` (or some other semantic operation)
23030
+ * during canonicalization.
23031
+ *
23032
+ * - `Sequence` is used to represent a sequence of expressions
23033
+ * at a semantic level. It is a collection, but it is handled
23034
+ * specially when canonicalizing expressions, for example it
23035
+ * is automatically flattened and hoisted to the top level of the
23036
+ * argument list.
23037
+ * For example:
23038
+ * `["Add", "a", ["Sequence", "b", "c"]]` is canonicalized
23039
+ * to `["Add", "a", "b", "c"]`.
23040
+ *
23041
+ * The empty `Sequence` expression (i.e. `["Sequence"]`) is ignored
23042
+ * but it can be used to represent an "empty" expression.
23043
+ *
23044
+ * - `Delimiter` is used to represent a group of expressions
23045
+ * with an open and close delimiter and separator. They capture the
23046
+ * input syntax, and can get transformed into other expressions
23047
+ * during boxing and canonicalization.
23048
+ * The first argument is a function expression, such as `List`
23049
+ * or `Sequence`. The arguments of that expression are represented
23050
+ * with a separator between them and delimiters around the whole
23051
+ * group.
23052
+ * The second argument specify the separator and delimiters. If not
23053
+ * specified, the default is the string `"(,)"`
23054
+ *
23055
+ * Examples:
23056
+ * - `f(x)` ->
23057
+ * `["InvisibleOperator",
23058
+ * "f",
23059
+ * ["Delimiter", ["Sequence", "x"], "'(,)'"]
23060
+ * ]`
23061
+ *
23062
+ * - `1, 2; 3, 4` ->
23063
+ * `["Delimiter",
23064
+ * ["Sequence",
23065
+ * ["Delimiter", ["Sequence", 1, 2], "','"],
23066
+ * ["Delimiter", ["Sequence", 3, 4], "','"],
23067
+ * ],
23068
+ * "';'"
23069
+ * ]`
23070
+ *
23071
+ * - `2x` -> `["InvisibleOperator", 2, "x"]`
23072
+ *
23073
+ * - `2+` -> `["InvisibleOperator", 2, ["Error", "'unexpected-operator'", "+"]]`
23074
+ *
23075
+ *
23076
+ *
23077
+ *
23078
+ */
23079
+ InvisibleOperator: {
23080
+ complexity: 9e3,
23081
+ hold: "all",
23082
+ signature: {
23083
+ restParam: "Anything",
23084
+ result: (ce, args) => {
23085
+ if (args.length === 0)
23086
+ return ce.domain("NothingDomain");
23087
+ if (args.length === 1)
23088
+ return args[0].domain;
23089
+ return ce.Anything;
23090
+ },
23091
+ canonical: canonicalInvisibleOperator
23092
+ }
23093
+ },
23094
+ /** See above for a theory of operations */
23095
+ Sequence: {
23096
+ hold: "all",
23097
+ signature: {
23098
+ restParam: "Anything",
23099
+ result: (ce, args) => {
23100
+ if (args.length === 0)
23101
+ return ce.domain("NothingDomain");
23102
+ if (args.length === 1)
23103
+ return args[0].domain;
23104
+ return ce.Anything;
23105
+ },
23106
+ canonical: (ce, args) => {
23107
+ const xs = canonical(flattenSequence(args));
23108
+ if (xs.length === 0)
23109
+ return ce._fn("Sequence", []);
23110
+ if (xs.length === 1)
23111
+ return xs[0];
23112
+ return ce._fn("Sequence", xs);
23113
+ }
23114
+ }
23115
+ },
23116
+ /** See above for a theory of operations */
22627
23117
  Delimiter: {
22628
- // Use to represent groups of expressions. Named after https://en.wikipedia.org/wiki/Delimiter
23118
+ // Use to represent groups of expressions.
23119
+ // Named after https://en.wikipedia.org/wiki/Delimiter
22629
23120
  complexity: 9e3,
22630
- hold: "first",
23121
+ hold: "all",
22631
23122
  signature: {
22632
- domain: [
22633
- "FunctionOf",
22634
- "Anything",
22635
- ["OptArg", "Strings", "Strings"],
22636
- "Anything"
22637
- ],
23123
+ params: ["Anything"],
23124
+ optParams: ["Strings"],
22638
23125
  result: (_ce, args) => args[0].domain,
22639
- canonical: (ce, args) => args[0]?.canonical ?? ce.box(["Sequence"])
23126
+ // During canonicalization, Delimiters get replaced by their first
23127
+ // argument, which is a function expression (e.g. `List` or `Sequence`)
23128
+ canonical: (ce, args) => {
23129
+ if (args.length === 0)
23130
+ return ce._fn("Tuple", []);
23131
+ let body = args[0];
23132
+ console.assert(body.ops !== null);
23133
+ if (body.head === "Sequence")
23134
+ body = ce._fn("Sequence", ce.canonical(body.ops));
23135
+ args = [body, ...args.slice(1)];
23136
+ if (args.length === 1)
23137
+ return ce._fn("Delimiter", args);
23138
+ if (args.length > 2)
23139
+ return ce._fn("Delimiter", checkArity(ce, args, 2));
23140
+ if ((args[1].string?.length ?? 0) > 3) {
23141
+ return ce._fn("Delimiter", [
23142
+ args[0],
23143
+ ce.error("invalid-delimiter", args[1])
23144
+ ]);
23145
+ }
23146
+ return ce._fn("Delimiter", [
23147
+ args[0],
23148
+ checkDomain(ce, args[1], "Strings")
23149
+ ]);
23150
+ },
23151
+ evaluate: (ce, ops2) => {
23152
+ if (ops2.length === 0)
23153
+ return ce.Nothing;
23154
+ const op12 = ops2[0];
23155
+ if (op12.head === "Sequence" || op12.head === "Delimiter")
23156
+ ops2 = flattenSequence(ops2[0].ops);
23157
+ return ce._fn(
23158
+ "Tuple",
23159
+ ops2.map((x) => x.evaluate())
23160
+ );
23161
+ },
23162
+ N: (ce, ops2) => {
23163
+ if (ops2.length === 0)
23164
+ return ce.Nothing;
23165
+ const op12 = ops2[0];
23166
+ if (op12.head === "Sequence" || op12.head === "Delimiter")
23167
+ ops2 = flattenSequence(ops2[0].ops);
23168
+ return ce._fn(
23169
+ "Tuple",
23170
+ ops2.map((x) => x.N())
23171
+ );
23172
+ }
23173
+ }
23174
+ },
23175
+ Matrix: {
23176
+ complexity: 9e3,
23177
+ hold: "all",
23178
+ signature: {
23179
+ params: ["Lists"],
23180
+ optParams: ["Strings", "Strings"],
23181
+ result: "Lists",
23182
+ canonical: canonicalMatrix,
23183
+ evaluate: (_ce, ops2) => ops2[0].evaluate(),
23184
+ N: (_ce, ops2) => ops2[0].N()
22640
23185
  }
22641
23186
  },
22642
23187
  Error: {
@@ -22661,7 +23206,7 @@ var ComputeEngine = (() => {
22661
23206
  signature: {
22662
23207
  domain: ["FunctionOf", "Strings", ["VarArg", "Anything"], "Anything"],
22663
23208
  canonical: (ce, args) => {
22664
- const code = checkArg(ce, args[0], ce.Strings).string;
23209
+ const code = checkDomain(ce, args[0], ce.Strings).string;
22665
23210
  if (code === "incompatible-domain") {
22666
23211
  return ce._fn("ErrorCode", [ce.string(code), args[1], args[2]]);
22667
23212
  }
@@ -22681,11 +23226,11 @@ var ComputeEngine = (() => {
22681
23226
  return ce.domain("Strings");
22682
23227
  if (op12.head === "Numbers")
22683
23228
  return ce.domain("Numbers");
22684
- return void 0;
23229
+ return op12.domain;
22685
23230
  },
22686
23231
  // By definition, for arguments of the canonical expression of
22687
23232
  // `Hold` are not canonicalized.
22688
- canonical: (ce, args) => args.length !== 1 ? null : ce._fn("Hold", args),
23233
+ canonical: (ce, args) => args.length !== 1 ? null : ce.hold(args[0]),
22689
23234
  evaluate: (ce, ops2) => ops2[0]
22690
23235
  }
22691
23236
  },
@@ -22780,18 +23325,17 @@ var ComputeEngine = (() => {
22780
23325
  },
22781
23326
  Assign: {
22782
23327
  hold: "all",
23328
+ pure: false,
22783
23329
  signature: {
22784
- domain: ["FunctionOf", "Symbols", "Anything", "Anything"],
23330
+ domain: ["FunctionOf", "Anything", "Anything", "Anything"],
22785
23331
  canonical: (ce, args) => {
22786
23332
  if (args.length !== 2)
22787
23333
  return null;
22788
23334
  const op12 = args[0];
22789
- const op22 = args[1];
22790
23335
  if (!op12.symbol)
22791
23336
  return null;
22792
- if (op22.symbol)
22793
- return ce._fn("Assign", args);
22794
- return ce._fn("Assign", [op12, ce._fn("Hold", [op22])]);
23337
+ const op22 = args[1];
23338
+ return ce._fn("Assign", [ce.hold(op12), ce.hold(op22)]);
22795
23339
  },
22796
23340
  evaluate: (ce, ops2) => {
22797
23341
  const op12 = ops2[0];
@@ -22806,6 +23350,7 @@ var ComputeEngine = (() => {
22806
23350
  },
22807
23351
  Assume: {
22808
23352
  hold: "all",
23353
+ pure: false,
22809
23354
  signature: {
22810
23355
  domain: ["FunctionOf", "Anything", "Anything"],
22811
23356
  evaluate: (ce, ops2) => ce.string(ce.assume(ops2[0]))
@@ -22813,6 +23358,7 @@ var ComputeEngine = (() => {
22813
23358
  },
22814
23359
  Declare: {
22815
23360
  hold: "all",
23361
+ pure: false,
22816
23362
  signature: {
22817
23363
  domain: ["FunctionOf", "Symbols", "Anything"],
22818
23364
  canonical: (ce, args) => {
@@ -22966,17 +23512,15 @@ var ComputeEngine = (() => {
22966
23512
  const op22 = args[1];
22967
23513
  if (op12.string) {
22968
23514
  const base = asSmallInteger(op22);
22969
- if (base !== null) {
22970
- if (base > 1 && base <= 36) {
22971
- const [value, rest] = fromDigits(op12.string, base);
22972
- if (rest) {
22973
- return ce.error(
22974
- ["unexpected-digit", { str: rest[0] }],
22975
- ["LatexString", ce.string(op12.string)]
22976
- );
22977
- }
22978
- return ce.number(value);
23515
+ if (base !== null && base > 1 && base <= 36) {
23516
+ const [value, rest] = fromDigits(op12.string, base);
23517
+ if (rest) {
23518
+ return ce.error(
23519
+ ["unexpected-digit", { str: rest[0] }],
23520
+ ["LatexString", ce.string(op12.string)]
23521
+ );
22979
23522
  }
23523
+ return ce.number(value);
22980
23524
  }
22981
23525
  }
22982
23526
  if (op12.symbol) {
@@ -23094,6 +23638,56 @@ var ComputeEngine = (() => {
23094
23638
  }
23095
23639
  }
23096
23640
  ];
23641
+ function canonicalInvisibleOperator(ce, ops2) {
23642
+ if (ops2.length === 0)
23643
+ return null;
23644
+ const lhs = ops2[0];
23645
+ if (ops2.length === 1)
23646
+ return canonicalInvisibleOperator(ce, [lhs.canonical]);
23647
+ if (ops2.length === 2) {
23648
+ const lhsNumber = asFloat(lhs);
23649
+ if (lhsNumber !== null && Number.isInteger(lhsNumber)) {
23650
+ const rhs2 = ops2[1];
23651
+ if (rhs2.head === "Divide" || rhs2.head === "Rational") {
23652
+ const [n, d] = [asFloat(rhs2.op1), asFloat(rhs2.op2)];
23653
+ if (n !== null && d !== null && n > 0 && n <= 1e3 && d > 1 && d <= 1e3 && Number.isInteger(n) && Number.isInteger(d))
23654
+ return ce.add([lhs.canonical, rhs2.canonical]);
23655
+ }
23656
+ }
23657
+ let rhs = ops2[1];
23658
+ if (lhs.symbol && rhs.head === "Delimiter" && !ce.lookupSymbol(lhs.symbol)) {
23659
+ if (!ce.lookupFunction(lhs.symbol)) {
23660
+ ce.declare(lhs.symbol, "Functions");
23661
+ }
23662
+ if (rhs.nops === 0)
23663
+ return ce.box([lhs.symbol]);
23664
+ rhs = rhs.op1;
23665
+ if (rhs.head === "Sequence")
23666
+ return ce.box([lhs.symbol, ...ce.canonical(rhs.ops)]);
23667
+ return ce.box([lhs.symbol, rhs.canonical]);
23668
+ }
23669
+ }
23670
+ ops2 = canonical(flattenSequence(ops2));
23671
+ if (ops2.every(
23672
+ (x) => x.isValid && (!x.domain || x.domain.isNumeric || isIndexableCollection(x) && !x.string)
23673
+ ))
23674
+ return ce._fn("Multiply", flattenOps(ops2, "Multiply"));
23675
+ return ce._fn("Tuple", ops2);
23676
+ }
23677
+ function canonicalMatrix(ce, ops2) {
23678
+ if (ops2.length === 0)
23679
+ return ce._fn("Matrix", []);
23680
+ const body = ops2[0].canonical;
23681
+ const delims = ops2[1]?.canonical;
23682
+ const columns = ops2[2]?.canonical;
23683
+ if (ops2.length > 3)
23684
+ return ce._fn("Matrix", checkArity(ce, ops2, 3));
23685
+ if (columns)
23686
+ return ce._fn("Matrix", [body, delims, columns]);
23687
+ if (delims)
23688
+ return ce._fn("Matrix", [body, delims]);
23689
+ return ce._fn("Matrix", [body]);
23690
+ }
23097
23691
 
23098
23692
  // src/compute-engine/library/linear-algebra.ts
23099
23693
  var LINEAR_ALGEBRA_LIBRARY = [];
@@ -23161,6 +23755,15 @@ var ComputeEngine = (() => {
23161
23755
  complexity: 10200,
23162
23756
  signature: {
23163
23757
  domain: "LogicOperators",
23758
+ canonical: (ce, args) => {
23759
+ const lhs = args[0].symbol;
23760
+ const rhs = args[1].symbol;
23761
+ if (lhs === "True" && rhs === "True" || lhs === "False" && rhs === "False")
23762
+ return ce.True;
23763
+ if (lhs === "True" && rhs === "False" || lhs === "False" && rhs === "True")
23764
+ return ce.False;
23765
+ return ce._fn("Equivalent", args);
23766
+ },
23164
23767
  simplify: processEquivalent,
23165
23768
  evaluate: processEquivalent
23166
23769
  }
@@ -23230,7 +23833,7 @@ var ComputeEngine = (() => {
23230
23833
  return ce._fn("Or", ops2);
23231
23834
  }
23232
23835
  function processNot(ce, args) {
23233
- const op12 = args[0].symbol;
23836
+ const op12 = args[0]?.symbol;
23234
23837
  if (op12 === "True")
23235
23838
  return ce.False;
23236
23839
  if (op12 === "False")
@@ -23294,17 +23897,42 @@ var ComputeEngine = (() => {
23294
23897
 
23295
23898
  // src/compute-engine/library/relational-operator.ts
23296
23899
  var RELOP_LIBRARY = {
23900
+ Congruent: {
23901
+ commutative: false,
23902
+ complexity: 11e3,
23903
+ numeric: true,
23904
+ signature: {
23905
+ simplify: (ce, ops2) => {
23906
+ if (ops2.length < 3)
23907
+ return void 0;
23908
+ return ce._fn("Equal", [
23909
+ ce.box(["Mod", ops2[0], ops2[2]]).simplify(),
23910
+ ce.box(["Mod", ops2[1], ops2[2]]).simplify()
23911
+ ]).simplify();
23912
+ },
23913
+ evaluate: (ce, ops2) => {
23914
+ if (ops2.length < 3)
23915
+ return void 0;
23916
+ const [lhs, rhs, modulo] = ops2;
23917
+ const nLhs = lhs.value;
23918
+ const nRhs = rhs.value;
23919
+ const nModulo = modulo.value;
23920
+ if (typeof nLhs !== "number")
23921
+ return void 0;
23922
+ if (typeof nRhs !== "number")
23923
+ return void 0;
23924
+ if (typeof nModulo !== "number")
23925
+ return void 0;
23926
+ return nLhs % nModulo === nRhs % nModulo ? ce.True : ce.False;
23927
+ }
23928
+ }
23929
+ },
23297
23930
  Equal: {
23298
23931
  commutative: true,
23299
23932
  complexity: 11e3,
23300
23933
  signature: {
23301
23934
  domain: "RelationalOperators",
23302
- canonical: (ce, ops2) => {
23303
- return ce._fn(
23304
- "Equal",
23305
- flattenOps(flattenSequence(canonical(ops2)), "Equal")
23306
- );
23307
- },
23935
+ canonical: (ce, args) => canonicalRelational(ce, "Equal", args),
23308
23936
  evaluate: (ce, ops2) => {
23309
23937
  if (ops2.length < 2)
23310
23938
  return ce.True;
@@ -23328,6 +23956,7 @@ var ComputeEngine = (() => {
23328
23956
  complexity: 11e3,
23329
23957
  signature: {
23330
23958
  domain: "RelationalOperators",
23959
+ canonical: (ce, args) => canonicalRelational(ce, "NotEqual", args),
23331
23960
  evaluate: (ce, ops2) => {
23332
23961
  if (ops2.length < 2)
23333
23962
  return ce.False;
@@ -23349,7 +23978,7 @@ var ComputeEngine = (() => {
23349
23978
  complexity: 11e3,
23350
23979
  signature: {
23351
23980
  domain: "RelationalOperators",
23352
- canonical: (ce, ops2) => ce._fn("Less", flattenOps(flattenSequence(canonical(ops2)), "Less")),
23981
+ canonical: (ce, ops2) => canonicalRelational(ce, "Less", ops2),
23353
23982
  evaluate: (ce, ops2) => {
23354
23983
  if (ops2.length < 2)
23355
23984
  return ce.True;
@@ -23376,14 +24005,14 @@ var ComputeEngine = (() => {
23376
24005
  complexity: 11e3,
23377
24006
  signature: {
23378
24007
  domain: "RelationalOperators",
23379
- canonical: (ce, args) => ce._fn("Not", [ce._fn("Less", args)])
24008
+ canonical: (ce, ops2) => ce._fn("Not", [canonicalRelational(ce, "Less", ops2)])
23380
24009
  }
23381
24010
  },
23382
24011
  Greater: {
23383
24012
  complexity: 11e3,
23384
24013
  signature: {
23385
24014
  domain: "RelationalOperators",
23386
- canonical: (ce, args) => ce._fn("Less", args.reverse()),
24015
+ canonical: (ce, ops2) => canonicalRelational(ce, "Less", ops2.reverse()),
23387
24016
  evaluate: (ce, ops2) => {
23388
24017
  if (ops2.length < 2)
23389
24018
  return ce.True;
@@ -23417,6 +24046,7 @@ var ComputeEngine = (() => {
23417
24046
  complexity: 11e3,
23418
24047
  signature: {
23419
24048
  domain: "RelationalOperators",
24049
+ canonical: (ce, ops2) => canonicalRelational(ce, "LessEqual", ops2),
23420
24050
  evaluate: (ce, ops2) => {
23421
24051
  if (ops2.length < 2)
23422
24052
  return ce.True;
@@ -23443,14 +24073,14 @@ var ComputeEngine = (() => {
23443
24073
  complexity: 11e3,
23444
24074
  signature: {
23445
24075
  domain: "RelationalOperators",
23446
- canonical: (ce, args) => ce._fn("Not", [ce._fn("LessEqual", args)])
24076
+ canonical: (ce, ops2) => ce._fn("Not", [canonicalRelational(ce, "LessEqual", ops2)])
23447
24077
  }
23448
24078
  },
23449
24079
  GreaterEqual: {
23450
24080
  complexity: 11e3,
23451
24081
  signature: {
23452
24082
  domain: "RelationalOperators",
23453
- canonical: (ce, args) => ce._fn("LessEqual", args.reverse()),
24083
+ canonical: (ce, args) => canonicalRelational(ce, "LessEqual", args.reverse()),
23454
24084
  evaluate: (ce, ops2) => {
23455
24085
  if (ops2.length < 2)
23456
24086
  return ce.True;
@@ -23477,94 +24107,136 @@ var ComputeEngine = (() => {
23477
24107
  complexity: 11e3,
23478
24108
  signature: {
23479
24109
  domain: "RelationalOperators",
23480
- canonical: (ce, args) => ce._fn("Not", [ce._fn("GreaterEqual", args)])
24110
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "GreaterEqual", args)])
23481
24111
  }
23482
24112
  },
23483
24113
  TildeFullEqual: {
23484
24114
  description: "Indicate isomorphism, congruence and homotopic equivalence",
23485
- signature: { domain: "RelationalOperators" }
24115
+ signature: {
24116
+ domain: "RelationalOperators",
24117
+ canonical: (ce, args) => canonicalRelational(ce, "TildeFullEqual", args)
24118
+ }
23486
24119
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23487
24120
  },
23488
24121
  NotTildeFullEqual: {
23489
24122
  complexity: 11100,
23490
24123
  signature: {
23491
24124
  domain: "RelationalOperators",
23492
- canonical: (ce, args) => ce._fn("Not", [ce._fn("TildeFullEqual", args)])
24125
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "TildeFullEqual", args)])
23493
24126
  }
23494
24127
  },
23495
24128
  TildeEqual: {
23496
24129
  description: "Approximately or asymptotically equal",
23497
24130
  complexity: 11e3,
23498
- signature: { domain: "RelationalOperators" }
24131
+ signature: {
24132
+ domain: "RelationalOperators",
24133
+ canonical: (ce, args) => canonicalRelational(ce, "TildeEqual", args)
24134
+ }
23499
24135
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23500
24136
  },
23501
24137
  NotTildeEqual: {
23502
24138
  complexity: 11100,
23503
24139
  signature: {
23504
24140
  domain: "RelationalOperators",
23505
- canonical: (ce, args) => ce._fn("Not", [ce._fn("TildeEqual", args)])
24141
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "TildeEqual", args)])
23506
24142
  }
23507
24143
  },
23508
24144
  Approx: {
23509
24145
  complexity: 11100,
23510
- signature: { domain: "RelationalOperators" }
24146
+ signature: {
24147
+ domain: "RelationalOperators",
24148
+ canonical: (ce, args) => canonicalRelational(ce, "Approx", args)
24149
+ }
23511
24150
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23512
24151
  },
23513
24152
  NotApprox: {
23514
24153
  complexity: 11100,
23515
24154
  signature: {
23516
24155
  domain: "RelationalOperators",
23517
- canonical: (ce, args) => ce._fn("Not", [ce._fn("Approx", args)])
24156
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "Approx", args)])
23518
24157
  }
23519
24158
  },
23520
24159
  ApproxEqual: {
23521
24160
  complexity: 11100,
23522
- signature: { domain: "RelationalOperators" }
24161
+ signature: {
24162
+ domain: "RelationalOperators",
24163
+ canonical: (ce, args) => canonicalRelational(ce, "ApproxEqual", args)
24164
+ }
23523
24165
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23524
24166
  },
23525
24167
  NotApproxEqual: {
23526
24168
  complexity: 11100,
23527
24169
  signature: {
23528
24170
  domain: "RelationalOperators",
23529
- canonical: (ce, args) => ce._fn("Not", [ce._fn("ApproxEqual", args)])
24171
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "ApproxEqual", args)])
23530
24172
  }
23531
24173
  },
23532
24174
  ApproxNotEqual: {
23533
24175
  complexity: 11100,
23534
- signature: { domain: "RelationalOperators" }
24176
+ signature: {
24177
+ domain: "RelationalOperators",
24178
+ canonical: (ce, args) => canonicalRelational(ce, "ApproxNotEqual", args)
24179
+ }
23535
24180
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23536
24181
  },
23537
24182
  NotApproxNotEqual: {
23538
24183
  complexity: 11100,
23539
24184
  signature: {
23540
24185
  domain: "RelationalOperators",
23541
- canonical: (ce, args) => ce._fn("Not", [ce._fn("ApproxNotEqual", args)])
24186
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "ApproxNotEqual", args)])
23542
24187
  }
23543
24188
  },
23544
24189
  Precedes: {
23545
24190
  complexity: 11100,
23546
- signature: { domain: "RelationalOperators" }
24191
+ signature: {
24192
+ domain: "RelationalOperators",
24193
+ canonical: (ce, args) => canonicalRelational(ce, "Precedes", args)
24194
+ }
23547
24195
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23548
24196
  },
23549
24197
  NotPrecedes: {
23550
24198
  complexity: 11100,
23551
24199
  signature: {
23552
24200
  domain: "RelationalOperators",
23553
- canonical: (ce, args) => ce._fn("Not", [ce._fn("Precedes", args)])
24201
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "Precedes", args)])
23554
24202
  }
23555
24203
  },
23556
24204
  Succeeds: {
23557
- signature: { domain: "RelationalOperators" }
24205
+ signature: {
24206
+ domain: "RelationalOperators",
24207
+ canonical: (ce, args) => canonicalRelational(ce, "Succeeds", args)
24208
+ }
23558
24209
  // @todo evaluate: (ce, ...args: BoxedExpression[]) => SemiBoxedExpression {}
23559
24210
  },
23560
24211
  NotSucceeds: {
23561
24212
  complexity: 11100,
23562
24213
  signature: {
23563
24214
  domain: "RelationalOperators",
23564
- canonical: (ce, args) => ce._fn("Not", [ce._fn("Succeeds", args)])
24215
+ canonical: (ce, args) => ce._fn("Not", [canonicalRelational(ce, "Succeeds", args)])
23565
24216
  }
23566
24217
  }
23567
24218
  };
24219
+ function canonicalRelational(ce, head2, ops2) {
24220
+ ops2 = flattenOps(flattenSequence(canonical(ops2)), head2);
24221
+ const nestedRelational = [];
24222
+ let newOps = [];
24223
+ for (const op3 of ops2) {
24224
+ if (isRelationalOperator(op3)) {
24225
+ nestedRelational.push(op3);
24226
+ newOps.push(op3.ops[op3.ops.length - 1]);
24227
+ } else
24228
+ newOps.push(op3);
24229
+ }
24230
+ newOps = newOps.map((op3) => checkPure(ce, op3));
24231
+ if (nestedRelational.length === 0)
24232
+ return ce._fn(head2, newOps);
24233
+ return ce._fn("And", [ce._fn(head2, newOps), ...nestedRelational]);
24234
+ }
24235
+ function isRelationalOperator(op3) {
24236
+ return typeof op3.head === "string" && /Equal|NotEqual|Less|NotLess|Greater|NotGreater|LessEqual|NotLessNotEqual|GreaterEqual|NotGreater|NotEqual|TildeFullEqual|NotTildeFullEqual|TildeEqual|NotTildeEqual|Approx|NotApprox|ApproxEqual|NotApproxEqual|ApproxNotEqual|NotApproxNotEqual|Precedes|NotPrecedes|Succeeds|NotSucceeds/.test(
24237
+ op3.head
24238
+ );
24239
+ }
23568
24240
 
23569
24241
  // src/compute-engine/library/sets.ts
23570
24242
  var SETS_LIBRARY = {
@@ -26362,14 +27034,7 @@ ${JSON.stringify(entry)}`
26362
27034
  return this._hash;
26363
27035
  }
26364
27036
  get isPure() {
26365
- const def = this._def ?? this.engine.lookupSymbol(this._id, this.wikidata);
26366
- if (!def)
26367
- return false;
26368
- if (def instanceof _BoxedSymbolDefinition)
26369
- return (def?.constant && def.value?.isPure) ?? false;
26370
- if (def instanceof _BoxedFunctionDefinition)
26371
- return def?.pure ?? false;
26372
- return false;
27037
+ return true;
26373
27038
  }
26374
27039
  get json() {
26375
27040
  const wikidata = this._scope ? this.wikidata : void 0;
@@ -26878,15 +27543,15 @@ ${JSON.stringify(entry)}`
26878
27543
  TranscendentalNumbers: null,
26879
27544
  PositiveNumbers: null,
26880
27545
  Functions: null,
26881
- // (Anything^n) -> Anything
27546
+ // (Anything*) -> Anything
26882
27547
  NumericFunctions: null,
26883
- // (Numbers^n) -> Numbers
27548
+ // (Numbers+) -> Numbers
26884
27549
  RealFunctions: null,
26885
- // (ExtendedRealNumbers^n) -> ExtendRealNumbers
27550
+ // (ExtendedRealNumbers+) -> ExtendRealNumbers
26886
27551
  LogicOperators: null,
26887
- // (Booleans, Booleans) -> Boolean
27552
+ // (Booleans+) -> Boolean
26888
27553
  Predicates: null
26889
- // (Anything^n) -> Booleans
27554
+ // (Anything+) -> Booleans
26890
27555
  };
26891
27556
  if (options !== void 0 && typeof options !== "object")
26892
27557
  throw Error("Unexpected argument");
@@ -27158,7 +27823,12 @@ ${JSON.stringify(entry)}`
27158
27823
  bignum(a) {
27159
27824
  if (typeof a === "bigint")
27160
27825
  return new this._bignum(a.toString());
27161
- return new this._bignum(a);
27826
+ try {
27827
+ return new this._bignum(a);
27828
+ } catch (e) {
27829
+ console.error(e);
27830
+ }
27831
+ return this._BIGNUM_NAN;
27162
27832
  }
27163
27833
  complex(a, b) {
27164
27834
  if (a instanceof Decimal)
@@ -27507,11 +28177,10 @@ ${JSON.stringify(entry)}`
27507
28177
  const scope = symDef.scope;
27508
28178
  scope?.ids?.delete(symDef.name);
27509
28179
  if (!args && !isFunctionValue(value)) {
27510
- if (value === void 0 || value === null) {
28180
+ if (value === void 0 || value === null)
27511
28181
  symDef.value = void 0;
27512
- return this;
27513
- }
27514
- symDef.value = this.box(value);
28182
+ else
28183
+ symDef.value = this.box(value);
27515
28184
  scope?.ids?.set(symDef.name, symDef);
27516
28185
  return this;
27517
28186
  }
@@ -28144,10 +28813,10 @@ ${JSON.stringify(entry)}`
28144
28813
  }
28145
28814
 
28146
28815
  // src/compute-engine.ts
28147
- var version = "0.19.1";
28816
+ var version = "0.20.0";
28148
28817
  globalThis[Symbol.for("io.cortexjs.compute-engine")] = {
28149
28818
  ComputeEngine: ComputeEngine.prototype.constructor,
28150
- version: "0.19.1"
28819
+ version: "0.20.0"
28151
28820
  };
28152
28821
  return __toCommonJS(compute_engine_exports);
28153
28822
  })();